mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-17 00:09:36 -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):
|
||||
'''Returns the full name of the 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
|
||||
return "Generic algorithm provider"
|
||||
|
||||
def getIcon(self):
|
||||
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/alg.png")
|
||||
|
@ -408,5 +408,21 @@ class GeoAlgorithm:
|
||||
s+=out.getValueAsCommandLineParameter() + ","
|
||||
s= s[:-1] + ")"
|
||||
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:
|
||||
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>")
|
||||
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
|
||||
|
||||
|
||||
@ -463,3 +463,16 @@ class GrassAlgorithm(GeoAlgorithm):
|
||||
func = getattr(module,'checkParameterValuesBeforeExecuting')
|
||||
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):
|
||||
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):
|
||||
return ["shp"]
|
||||
|
||||
|
@ -325,7 +325,6 @@ class GrassUtils:
|
||||
if not ignoreRegistrySettings:
|
||||
if settings.contains(GRASS_INSTALLED):
|
||||
return
|
||||
|
||||
try:
|
||||
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)
|
||||
|
@ -42,7 +42,7 @@ class CouldNotLoadResultsDialog(QtGui.QDialog):
|
||||
webView = QtWebKit.QWebView()
|
||||
webView.page().setLinkDelegationPolicy(QtWebKit.QWebPage.DelegateAllLinks)
|
||||
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)
|
||||
closeButton = QtGui.QPushButton()
|
||||
closeButton.setText("Close")
|
||||
|
@ -270,22 +270,19 @@ class RAlgorithm(GeoAlgorithm):
|
||||
|
||||
def getImportCommands(self):
|
||||
commands = []
|
||||
# if rgdal is not available, try to install it
|
||||
|
||||
# just use main mirror
|
||||
commands.append('options("repos"="http://cran.at.r-project.org/")')
|
||||
rLibDir = "%s/rlibs" % SextanteUtils.userFolder().replace("\\","/")
|
||||
if not os.path.isdir(rLibDir):
|
||||
os.mkdir(rLibDir)
|
||||
# .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!
|
||||
commands.append('deflibloc <- .libPaths()[1]')
|
||||
commands.append('.libPaths(c("%s",deflibloc))' % rLibDir )
|
||||
commands.append(
|
||||
'tryCatch(find.package("rgdal"), error=function(e) install.packages("rgdal", dependencies=TRUE, lib="%s"))' % rLibDir)
|
||||
commands.append("library(\"rgdal\")");
|
||||
#if not self.useRasterPackage or self.passFileNames:
|
||||
commands.append(
|
||||
'tryCatch(find.package("raster"), error=function(e) install.packages("raster", dependencies=TRUE, lib="%s"))' % rLibDir)
|
||||
commands.append("library(\"raster\")");
|
||||
|
||||
# try to install packages if needed
|
||||
packages = RUtils.getRequiredPackages(self.script)
|
||||
packages.extend(['rgdal', 'raster'])
|
||||
for p in packages:
|
||||
commands.append(
|
||||
'tryCatch(find.package("' + p +
|
||||
'"), error=function(e) install.packages("' + p +'", dependencies=TRUE))')
|
||||
commands.append('library("raster")')
|
||||
commands.append('library("rgdal")')
|
||||
|
||||
for param in self.parameters:
|
||||
if isinstance(param, ParameterRaster):
|
||||
@ -386,28 +383,28 @@ class RAlgorithm(GeoAlgorithm):
|
||||
return None
|
||||
|
||||
def checkBeforeOpeningParametersDialog(self):
|
||||
if SextanteUtils.isWindows():
|
||||
path = RUtils.RFolder()
|
||||
if path == "":
|
||||
return "R folder is not configured.\nPlease configure it before running R scripts."
|
||||
msg = RUtils.checkRIsInstalled()
|
||||
if msg is not None:
|
||||
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>")
|
||||
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()
|
||||
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"]
|
||||
|
||||
def getPostProcessingErrorMessage(self, wrongLayers):
|
||||
html = GeoAlgorithm.getPostProcessingErrorMessage(self, wrongLayers)
|
||||
msg = RUtils.checkRIsInstalled(True)
|
||||
html += ("<p>This algorithm requires R to be run. A test to check if R 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>"
|
||||
html += "<p>The script you have executed needs the following packages:</p><ul>"
|
||||
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:
|
||||
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
|
||||
return "It seems that R is not correctly installed in your system.\nPlease install it before running R Scripts."
|
||||
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 R to be used with SEXTANTE</p>'
|
||||
|
||||
return html
|
||||
|
@ -16,6 +16,7 @@
|
||||
* *
|
||||
***************************************************************************
|
||||
"""
|
||||
import re
|
||||
|
||||
__author__ = 'Victor Olaya'
|
||||
__date__ = 'August 2012'
|
||||
@ -24,6 +25,7 @@ __copyright__ = '(C) 2012, Victor Olaya'
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
from sextante.core.SextanteConfig import SextanteConfig
|
||||
import os
|
||||
from sextante.core.SextanteUtils import mkdir, SextanteUtils
|
||||
@ -123,3 +125,41 @@ class RUtils:
|
||||
s+="</font>\n"
|
||||
|
||||
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:
|
||||
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>")
|
||||
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
|
||||
|
||||
|
||||
@ -379,7 +379,18 @@ class SagaAlgorithm(GeoAlgorithm):
|
||||
def helpFile(self):
|
||||
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):
|
||||
# name = self.provider.getName().lower() + ":" + self.cmdname.lower()
|
||||
|
@ -99,19 +99,6 @@ class SagaAlgorithmProvider(AlgorithmProvider):
|
||||
def getName(self):
|
||||
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):
|
||||
return ["shp"]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user