Restore ability to run script algorithms

This commit is contained in:
Nyall Dawson 2017-06-26 15:48:21 +10:00
parent df329bceab
commit 3bf9ea3682
2 changed files with 31 additions and 15 deletions

View File

@ -44,6 +44,7 @@ from qgis.core import (QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsCoordinat
QgsProject, QgsProject,
QgsRectangle, QgsRectangle,
QgsVectorFileWriter, QgsVectorFileWriter,
QgsProcessingParameters,
QgsProcessingParameterDefinition) QgsProcessingParameterDefinition)
from processing.tools.vector import resolveFieldIndex from processing.tools.vector import resolveFieldIndex
@ -602,6 +603,13 @@ def getParameterFromString(s):
except: except:
return None return None
else: # try script syntax else: # try script syntax
# try native method
param = QgsProcessingParameters.parameterFromScriptCode(s)
if param:
return param
# try Python duck-typed method
for paramClass in paramClasses: for paramClass in paramClasses:
try: try:
param = paramClass.fromScriptCode(s) param = paramClass.fromScriptCode(s)

View File

@ -64,7 +64,7 @@ class ScriptAlgorithm(QgsProcessingAlgorithm):
self._name = '' self._name = ''
self._display_name = '' self._display_name = ''
self._group = '' self._group = ''
self._flags = 0 self._flags = None
self.script = script self.script = script
self.allowEdit = True self.allowEdit = True
@ -88,7 +88,10 @@ class ScriptAlgorithm(QgsProcessingAlgorithm):
return self._group return self._group
def flags(self): def flags(self):
return self._flags if self._flags is not None:
return QgsProcessingAlgorithm.Flags(self._flags)
else:
return QgsProcessingAlgorithm.flags(self)
def svgIconPath(self): def svgIconPath(self):
return QgsApplication.iconPath("processingScript.svg") return QgsApplication.iconPath("processingScript.svg")
@ -98,6 +101,7 @@ class ScriptAlgorithm(QgsProcessingAlgorithm):
self.script = '' self.script = ''
filename = os.path.basename(self.descriptionFile) filename = os.path.basename(self.descriptionFile)
self._name = filename[:filename.rfind('.')].replace('_', ' ') self._name = filename[:filename.rfind('.')].replace('_', ' ')
self._display_name = self._name
self._group = self.tr('User scripts', 'ScriptAlgorithm') self._group = self.tr('User scripts', 'ScriptAlgorithm')
with open(self.descriptionFile) as lines: with open(self.descriptionFile) as lines:
line = lines.readline() line = lines.readline()
@ -163,8 +167,8 @@ class ScriptAlgorithm(QgsProcessingAlgorithm):
if param is not None: if param is not None:
self.addParameter(param) self.addParameter(param)
elif out is not None: elif out is not None:
out.name = tokens[0] out.setName(tokens[0])
out.description = desc out.setDescription(desc)
self.addOutput(out) self.addOutput(out)
else: else:
raise WrongScriptException( raise WrongScriptException(
@ -173,33 +177,37 @@ class ScriptAlgorithm(QgsProcessingAlgorithm):
def processAlgorithm(self, parameters, context, feedback): def processAlgorithm(self, parameters, context, feedback):
ns = {} ns = {}
ns['feedback'] = feedback
ns['scriptDescriptionFile'] = self.descriptionFile ns['scriptDescriptionFile'] = self.descriptionFile
ns['context'] = context
for param in self.parameterDefinitions(): for param in self.parameterDefinitions():
ns[param.name] = parameters[param.name()] ns[param.name()] = parameters[param.name()]
for out in self.outputs: ns['self'] = self
ns[out.name] = out.value ns['parameters'] = parameters
ns['feedback'] = feedback
ns['context'] = context
# for out in self.outputDefinitions():
# ns[out.name()] = out.value
variables = re.findall('@[a-zA-Z0-9_]*', self.script) variables = re.findall('@[a-zA-Z0-9_]*', self.script)
script = 'import processing\n' script = 'import processing\n'
script += self.script script += self.script
context = self.createExpressionContext(parameters, context)
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.globalScope())
context.appendScope(QgsExpressionContextUtils.projectScope(QgsProject.instance()))
for var in variables: for var in variables:
varname = var[1:] varname = var[1:]
if context.hasVariable(varname): if context.hasVariable(varname):
script = script.replace(var, context.variable(varname)) script = script.replace(var, context.variable(varname))
else: else:
# messy - it's probably NOT a variable, and instead an email address or some other string containing '@'
QgsMessageLog.logMessage(self.tr('Cannot find variable: {0}').format(varname), self.tr('Processing'), QgsMessageLog.WARNING) QgsMessageLog.logMessage(self.tr('Cannot find variable: {0}').format(varname), self.tr('Processing'), QgsMessageLog.WARNING)
exec((script), ns) exec((script), ns)
for out in self.outputs: results = {}
out.setValue(ns[out.name]) for out in self.outputDefinitions():
results[out.name()] = ns[out.name()]
return results
def helpUrl(self): def helpUrl(self):
if self.descriptionFile is None: if self.descriptionFile is None: