mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-18 00:06:00 -04:00
Changed how postexecution errors are handled in algorithms caling external apps
Improved R error messages
This commit is contained in:
parent
765ac75f78
commit
7a73307a2b
@ -83,23 +83,7 @@ class AlgorithmProvider():
|
|||||||
|
|
||||||
def getDescription(self):
|
def getDescription(self):
|
||||||
'''Returns the full name of the provider'''
|
'''Returns the full name of the provider'''
|
||||||
return "Generic algorithm provider"
|
return "Generic algorithm provider"
|
||||||
|
|
||||||
def getPostProcessingErrorMessage(self, wrongLayers):
|
|
||||||
'''Returns the message to be shown to the user when after running an algorithm for this provider,
|
|
||||||
there is a problem loading the resulting layer.
|
|
||||||
This method should analyze if the problem is caused by wrong entry data, a wrong or missing
|
|
||||||
installation of a required 3rd party app, or any other cause, and create an error response accordingly.
|
|
||||||
Message is provided as an HTML code that will be displayed to the user, and which might contains
|
|
||||||
links to installation paths for missing 3rd party apps.
|
|
||||||
- wrongLayers: a list of Output objects that could not be loaded.'''
|
|
||||||
|
|
||||||
html ="<p>Oooops! SEXTANTE could not open the following output layers</p><ul>\n"
|
|
||||||
for layer in wrongLayers:
|
|
||||||
html += '<li>' + layer.description + ': <font size=3 face="Courier New" color="ff0000">' + layer.value + "</font></li>\n"
|
|
||||||
html +="</ul><p>The above files could not be opened, which probably indicates that they were not correctly produced by the executed algorithm</p>"
|
|
||||||
html +="<p>Checking the log information might help you see why those layers were not created as expected</p>"
|
|
||||||
return html
|
|
||||||
|
|
||||||
def getIcon(self):
|
def getIcon(self):
|
||||||
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/alg.png")
|
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/alg.png")
|
||||||
|
@ -408,5 +408,21 @@ class GeoAlgorithm:
|
|||||||
s+=out.getValueAsCommandLineParameter() + ","
|
s+=out.getValueAsCommandLineParameter() + ","
|
||||||
s= s[:-1] + ")"
|
s= s[:-1] + ")"
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
def getPostProcessingErrorMessage(self, wrongLayers):
|
||||||
|
'''Returns the message to be shown to the user when, after running this algorithm,
|
||||||
|
there is a problem loading the resulting layer.
|
||||||
|
This method should analyze if the problem is caused by wrong entry data, a wrong or missing
|
||||||
|
installation of a required 3rd party app, or any other cause, and create an error response accordingly.
|
||||||
|
Message is provided as an HTML code that will be displayed to the user, and which might contains
|
||||||
|
links to installation paths for missing 3rd party apps.
|
||||||
|
- wrongLayers: a list of Output objects that could not be loaded.'''
|
||||||
|
|
||||||
|
html ="<p>Oooops! SEXTANTE could not open the following output layers</p><ul>\n"
|
||||||
|
for layer in wrongLayers:
|
||||||
|
html += '<li>' + layer.description + ': <font size=3 face="Courier New" color="ff0000">' + layer.value + "</font></li>\n"
|
||||||
|
html +="</ul><p>The above files could not be opened, which probably indicates that they were not correctly produced by the executed algorithm</p>"
|
||||||
|
html +="<p>Checking the log information might help you see why those layers were not created as expected</p>"
|
||||||
|
return html
|
||||||
|
|
||||||
|
|
||||||
|
@ -449,7 +449,7 @@ class GrassAlgorithm(GeoAlgorithm):
|
|||||||
if msg is not None:
|
if msg is not None:
|
||||||
html = ("<p>This algorithm requires GRASS to be run."
|
html = ("<p>This algorithm requires GRASS to be run."
|
||||||
"Unfortunately, it seems that GRASS is not installed in your system, or it is not correctly configured to be used from QGIS</p>")
|
"Unfortunately, it seems that GRASS is not installed in your system, or it is not correctly configured to be used from QGIS</p>")
|
||||||
html += '<p><a href= "http://docs.qgis.org/html/en/docs/user_manual/sextante/3rdParty.html">Click here</a> to know more about how to install and configure GRASS to be used with SEXTANTE</p>'
|
html += '<p><a href= "http://docs.qgis.org/2.0/html/en/docs/user_manual/sextante/3rdParty.html">Click here</a> to know more about how to install and configure GRASS to be used with SEXTANTE</p>'
|
||||||
return html
|
return html
|
||||||
|
|
||||||
|
|
||||||
@ -463,3 +463,16 @@ class GrassAlgorithm(GeoAlgorithm):
|
|||||||
func = getattr(module,'checkParameterValuesBeforeExecuting')
|
func = getattr(module,'checkParameterValuesBeforeExecuting')
|
||||||
return func(self)
|
return func(self)
|
||||||
|
|
||||||
|
|
||||||
|
def getPostProcessingErrorMessage(self, wrongLayers):
|
||||||
|
html = GeoAlgorithm.getPostProcessingErrorMessage(self, wrongLayers)
|
||||||
|
msg = GrassUtils.checkGrassIsInstalled(True)
|
||||||
|
html += ("<p>This algorithm requires GRASS to be run. A test to check if GRASS is correctly installed "
|
||||||
|
"and configured in your system has been performed, with the following result:</p><ul><i>")
|
||||||
|
if msg is None:
|
||||||
|
html += "GRASS seems to be correctly installed and configured</i></li></ul>"
|
||||||
|
else:
|
||||||
|
html += msg + "</i></li></ul>"
|
||||||
|
html += '<p><a href= "http://docs.qgis.org/2.0/html/en/docs/user_manual/sextante/3rdParty.html">Click here</a> to know more about how to install and configure GRASS to be used with SEXTANTE</p>'
|
||||||
|
|
||||||
|
return html
|
||||||
|
@ -83,19 +83,6 @@ class GrassAlgorithmProvider(AlgorithmProvider):
|
|||||||
def getIcon(self):
|
def getIcon(self):
|
||||||
return QIcon(os.path.dirname(__file__) + "/../images/grass.png")
|
return QIcon(os.path.dirname(__file__) + "/../images/grass.png")
|
||||||
|
|
||||||
def getPostProcessingErrorMessage(self, wrongLayers):
|
|
||||||
html = AlgorithmProvider.getPostProcessingErrorMessage(self, wrongLayers)
|
|
||||||
msg = GrassUtils.checkGrassIsInstalled(True)
|
|
||||||
html += ("<p>This algorithm requires GRASS to be run. A test to check if GRASS is correctly installed "
|
|
||||||
"and configured in your system has been performed, with the following result:</p><ul><i>")
|
|
||||||
if msg is None:
|
|
||||||
html += "GRASS seems to be correctly installed and configured</li></ul>"
|
|
||||||
else:
|
|
||||||
html += msg + "</i></li></ul>"
|
|
||||||
html += '<p><a href= "http://docs.qgis.org/2.0/html/en/docs/user_manual/sextante/3rdParty.html">Click here</a> to know more about how to install and configure GRASS to be used with SEXTANTE</p>'
|
|
||||||
|
|
||||||
return html
|
|
||||||
|
|
||||||
def getSupportedOutputVectorLayerExtensions(self):
|
def getSupportedOutputVectorLayerExtensions(self):
|
||||||
return ["shp"]
|
return ["shp"]
|
||||||
|
|
||||||
|
@ -325,7 +325,6 @@ class GrassUtils:
|
|||||||
if not ignoreRegistrySettings:
|
if not ignoreRegistrySettings:
|
||||||
if settings.contains(GRASS_INSTALLED):
|
if settings.contains(GRASS_INSTALLED):
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from sextante import runalg
|
from sextante import runalg
|
||||||
result = runalg("grass:v.voronoi", points(),False,False,"270778.60198,270855.745301,4458921.97814,4458983.8488",-1,0.0001, 0, None)
|
result = runalg("grass:v.voronoi", points(),False,False,"270778.60198,270855.745301,4458921.97814,4458983.8488",-1,0.0001, 0, None)
|
||||||
|
@ -42,7 +42,7 @@ class CouldNotLoadResultsDialog(QtGui.QDialog):
|
|||||||
webView = QtWebKit.QWebView()
|
webView = QtWebKit.QWebView()
|
||||||
webView.page().setLinkDelegationPolicy(QtWebKit.QWebPage.DelegateAllLinks)
|
webView.page().setLinkDelegationPolicy(QtWebKit.QWebPage.DelegateAllLinks)
|
||||||
webView.connect(webView, SIGNAL("linkClicked(const QUrl&)"), self.linkClicked)
|
webView.connect(webView, SIGNAL("linkClicked(const QUrl&)"), self.linkClicked)
|
||||||
html = self.alg.provider.getPostProcessingErrorMessage(self.wrongLayers)
|
html = self.alg.getPostProcessingErrorMessage(self.wrongLayers)
|
||||||
webView.setHtml(html)
|
webView.setHtml(html)
|
||||||
closeButton = QtGui.QPushButton()
|
closeButton = QtGui.QPushButton()
|
||||||
closeButton.setText("Close")
|
closeButton.setText("Close")
|
||||||
|
@ -270,22 +270,19 @@ class RAlgorithm(GeoAlgorithm):
|
|||||||
|
|
||||||
def getImportCommands(self):
|
def getImportCommands(self):
|
||||||
commands = []
|
commands = []
|
||||||
# if rgdal is not available, try to install it
|
|
||||||
# just use main mirror
|
# just use main mirror
|
||||||
commands.append('options("repos"="http://cran.at.r-project.org/")')
|
commands.append('options("repos"="http://cran.at.r-project.org/")')
|
||||||
rLibDir = "%s/rlibs" % SextanteUtils.userFolder().replace("\\","/")
|
|
||||||
if not os.path.isdir(rLibDir):
|
# try to install packages if needed
|
||||||
os.mkdir(rLibDir)
|
packages = RUtils.getRequiredPackages(self.script)
|
||||||
# .libPaths("%s") substitutes the personal libPath with "%s"! With '.libPaths(c("%s",deflibloc))' it is added without replacing and we can use all installed R packages!
|
packages.extend(['rgdal', 'raster'])
|
||||||
commands.append('deflibloc <- .libPaths()[1]')
|
for p in packages:
|
||||||
commands.append('.libPaths(c("%s",deflibloc))' % rLibDir )
|
commands.append(
|
||||||
commands.append(
|
'tryCatch(find.package("' + p +
|
||||||
'tryCatch(find.package("rgdal"), error=function(e) install.packages("rgdal", dependencies=TRUE, lib="%s"))' % rLibDir)
|
'"), error=function(e) install.packages("' + p +'", dependencies=TRUE))')
|
||||||
commands.append("library(\"rgdal\")");
|
commands.append('library("raster")')
|
||||||
#if not self.useRasterPackage or self.passFileNames:
|
commands.append('library("rgdal")')
|
||||||
commands.append(
|
|
||||||
'tryCatch(find.package("raster"), error=function(e) install.packages("raster", dependencies=TRUE, lib="%s"))' % rLibDir)
|
|
||||||
commands.append("library(\"raster\")");
|
|
||||||
|
|
||||||
for param in self.parameters:
|
for param in self.parameters:
|
||||||
if isinstance(param, ParameterRaster):
|
if isinstance(param, ParameterRaster):
|
||||||
@ -386,28 +383,28 @@ class RAlgorithm(GeoAlgorithm):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def checkBeforeOpeningParametersDialog(self):
|
def checkBeforeOpeningParametersDialog(self):
|
||||||
if SextanteUtils.isWindows():
|
msg = RUtils.checkRIsInstalled()
|
||||||
path = RUtils.RFolder()
|
if msg is not None:
|
||||||
if path == "":
|
html = ("<p>This algorithm requires R to be run."
|
||||||
return "R folder is not configured.\nPlease configure it before running R scripts."
|
"Unfortunately, it seems that R is not installed in your system, or it is not correctly configured to be used from QGIS</p>")
|
||||||
|
html += '<p><a href= "http://docs.qgis.org/2.0/html/en/docs/user_manual/sextante/3rdParty.html">Click here</a> to know more about how to install and configure R to be used with SEXTANTE</p>'
|
||||||
|
return html
|
||||||
|
|
||||||
R_INSTALLED = "R_INSTALLED"
|
|
||||||
settings = QSettings()
|
def getPostProcessingErrorMessage(self, wrongLayers):
|
||||||
if settings.contains(R_INSTALLED):
|
html = GeoAlgorithm.getPostProcessingErrorMessage(self, wrongLayers)
|
||||||
return
|
msg = RUtils.checkRIsInstalled(True)
|
||||||
if SextanteUtils.isWindows():
|
html += ("<p>This algorithm requires R to be run. A test to check if R is correctly installed "
|
||||||
if SextanteConfig.getSetting(RUtils.R_USE64):
|
"and configured in your system has been performed, with the following result:</p><ul><i>")
|
||||||
execDir = "x64"
|
if msg is None:
|
||||||
else:
|
html += "GRASS seems to be correctly installed and configured</i></li></ul>"
|
||||||
execDir = "i386"
|
html += "<p>The script you have executed needs the following packages:</p><ul>"
|
||||||
command = [RUtils.RFolder() + os.sep + "bin" + os.sep + execDir + os.sep + "R.exe", "--version"]
|
packages = RUtils.getRequiredPackages(self.script)
|
||||||
|
for p in packages:
|
||||||
|
html += '<li>' + p + '</li>'
|
||||||
|
html += "</ul><p>Make sure they are installed in your R environment before trying to execute this script.</p>"
|
||||||
else:
|
else:
|
||||||
command = ["R --version"]
|
html += msg + "</i></li></ul>"
|
||||||
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,stderr=subprocess.STDOUT, universal_newlines=True).stdout
|
html += '<p><a href= "http://docs.qgis.org/2.0/html/en/docs/user_manual/sextante/3rdParty.html">Click here</a> to know more about how to install and configure R to be used with SEXTANTE</p>'
|
||||||
|
|
||||||
for line in iter(proc.readline, ""):
|
|
||||||
if "R version" in line:
|
|
||||||
settings.setValue(R_INSTALLED, True)
|
|
||||||
return
|
|
||||||
return "It seems that R is not correctly installed in your system.\nPlease install it before running R Scripts."
|
|
||||||
|
|
||||||
|
return html
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
"""
|
"""
|
||||||
|
import re
|
||||||
|
|
||||||
__author__ = 'Victor Olaya'
|
__author__ = 'Victor Olaya'
|
||||||
__date__ = 'August 2012'
|
__date__ = 'August 2012'
|
||||||
@ -24,6 +25,7 @@ __copyright__ = '(C) 2012, Victor Olaya'
|
|||||||
__revision__ = '$Format:%H$'
|
__revision__ = '$Format:%H$'
|
||||||
|
|
||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
|
from PyQt4.QtCore import *
|
||||||
from sextante.core.SextanteConfig import SextanteConfig
|
from sextante.core.SextanteConfig import SextanteConfig
|
||||||
import os
|
import os
|
||||||
from sextante.core.SextanteUtils import mkdir, SextanteUtils
|
from sextante.core.SextanteUtils import mkdir, SextanteUtils
|
||||||
@ -123,3 +125,41 @@ class RUtils:
|
|||||||
s+="</font>\n"
|
s+="</font>\n"
|
||||||
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def checkRIsInstalled(ignoreRegistrySettings=False):
|
||||||
|
if SextanteUtils.isWindows():
|
||||||
|
path = RUtils.RFolder()
|
||||||
|
if path == "":
|
||||||
|
return "R folder is not configured.\nPlease configure it before running R scripts."
|
||||||
|
|
||||||
|
R_INSTALLED = "R_INSTALLED"
|
||||||
|
settings = QSettings()
|
||||||
|
if not ignoreRegistrySettings:
|
||||||
|
if settings.contains(R_INSTALLED):
|
||||||
|
return
|
||||||
|
if SextanteUtils.isWindows():
|
||||||
|
if SextanteConfig.getSetting(RUtils.R_USE64):
|
||||||
|
execDir = "x64"
|
||||||
|
else:
|
||||||
|
execDir = "i386"
|
||||||
|
command = [RUtils.RFolder() + os.sep + "bin" + os.sep + execDir + os.sep + "R.exe", "--version"]
|
||||||
|
else:
|
||||||
|
command = ["R --version"]
|
||||||
|
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,stderr=subprocess.STDOUT, universal_newlines=True).stdout
|
||||||
|
|
||||||
|
for line in iter(proc.readline, ""):
|
||||||
|
if "R version" in line:
|
||||||
|
settings.setValue(R_INSTALLED, True)
|
||||||
|
return
|
||||||
|
html = ("<p>This algorithm requires R to be run."
|
||||||
|
"Unfortunately, it seems that R is not installed in your system, or it is not correctly configured to be used from QGIS</p>"
|
||||||
|
'<p><a href= "http://docs.qgis.org/2.0/html/en/docs/user_manual/sextante/3rdParty.html">Click here</a>'
|
||||||
|
'to know more about how to install and configure R to be used with SEXTANTE</p>')
|
||||||
|
return html
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getRequiredPackages(code):
|
||||||
|
regex = re.compile('library\("?(.*?)"?\)')
|
||||||
|
return regex.findall(code)
|
||||||
|
|
@ -362,7 +362,7 @@ class SagaAlgorithm(GeoAlgorithm):
|
|||||||
if msg is not None:
|
if msg is not None:
|
||||||
html = ("<p>This algorithm requires SAGA to be run."
|
html = ("<p>This algorithm requires SAGA to be run."
|
||||||
"Unfortunately, it seems that SAGA is not installed in your system, or it is not correctly configured to be used from QGIS</p>")
|
"Unfortunately, it seems that SAGA is not installed in your system, or it is not correctly configured to be used from QGIS</p>")
|
||||||
html += '<p><a href= "http://docs.qgis.org/html/en/docs/user_manual/sextante/3rdParty.html">Click here</a> to know more about how to install and configure SAGA to be used with SEXTANTE</p>'
|
html += '<p><a href= "http://docs.qgis.org/2.0/html/en/docs/user_manual/sextante/3rdParty.html">Click here</a> to know more about how to install and configure SAGA to be used with SEXTANTE</p>'
|
||||||
return html
|
return html
|
||||||
|
|
||||||
|
|
||||||
@ -379,7 +379,18 @@ class SagaAlgorithm(GeoAlgorithm):
|
|||||||
def helpFile(self):
|
def helpFile(self):
|
||||||
return os.path.join(os.path.dirname(__file__), "help", self.name.replace(" ", "") + ".html")
|
return os.path.join(os.path.dirname(__file__), "help", self.name.replace(" ", "") + ".html")
|
||||||
|
|
||||||
|
def getPostProcessingErrorMessage(self, wrongLayers):
|
||||||
|
html = GeoAlgorithm.getPostProcessingErrorMessage(self, wrongLayers)
|
||||||
|
msg = SagaUtils.checkSagaIsInstalled(True)
|
||||||
|
html += ("<p>This algorithm requires SAGA to be run. A test to check if SAGA is correctly installed "
|
||||||
|
"and configured in your system has been performed, with the following result:</p><ul><i>")
|
||||||
|
if msg is None:
|
||||||
|
html += "SAGA seems to be correctly installed and configured</li></ul>"
|
||||||
|
else:
|
||||||
|
html += msg + "</i></li></ul>"
|
||||||
|
html += '<p><a href= "http://docs.qgis.org/2.0/html/en/docs/user_manual/sextante/3rdParty.html">Click here</a> to know more about how to install and configure SAGA to be used with SEXTANTE</p>'
|
||||||
|
|
||||||
|
return html
|
||||||
#===========================================================================
|
#===========================================================================
|
||||||
# def commandLineName(self):
|
# def commandLineName(self):
|
||||||
# name = self.provider.getName().lower() + ":" + self.cmdname.lower()
|
# name = self.provider.getName().lower() + ":" + self.cmdname.lower()
|
||||||
|
@ -99,19 +99,6 @@ class SagaAlgorithmProvider(AlgorithmProvider):
|
|||||||
def getName(self):
|
def getName(self):
|
||||||
return "saga"
|
return "saga"
|
||||||
|
|
||||||
def getPostProcessingErrorMessage(self, wrongLayers):
|
|
||||||
html = AlgorithmProvider.getPostProcessingErrorMessage(self, wrongLayers)
|
|
||||||
msg = SagaUtils.checkSagaIsInstalled(True)
|
|
||||||
html += ("<p>This algorithm requires SAGA to be run. A test to check if SAGA is correctly installed "
|
|
||||||
"and configured in your system has been performed, with the following result:</p><ul><i>")
|
|
||||||
if msg is None:
|
|
||||||
html += "SAGA seems to be correctly installed and configured</li></ul>"
|
|
||||||
else:
|
|
||||||
html += msg + "</i></li></ul>"
|
|
||||||
html += '<p><a href= "http://docs.qgis.org/2.0/html/en/docs/user_manual/sextante/3rdParty.html">Click here</a> to know more about how to install and configure SAGA to be used with SEXTANTE</p>'
|
|
||||||
|
|
||||||
return html
|
|
||||||
|
|
||||||
def getSupportedOutputVectorLayerExtensions(self):
|
def getSupportedOutputVectorLayerExtensions(self):
|
||||||
return ["shp"]
|
return ["shp"]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user