Skip to content

Commit

Permalink
[processing] improvements for scripts and R scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
volaya committed Oct 5, 2016
1 parent efd73a4 commit 01f3808
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 197 deletions.
128 changes: 10 additions & 118 deletions python/plugins/processing/algs/r/RAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
from processing.core.outputs import OutputRaster
from processing.core.outputs import OutputHTML
from processing.core.outputs import OutputFile
from processing.core.parameters import getParameterFromString
from processing.core.outputs import getOutputFromString
from processing.tools import dataobjects
from processing.tools.system import isWindows
from processing.script.WrongScriptException import WrongScriptException
Expand Down Expand Up @@ -148,7 +150,6 @@ def createDescriptiveName(self, s):

def processParameterLine(self, line):
param = None
out = None
line = line.replace('#', '')
if line.lower().strip().startswith('showplots'):
self.showPlots = True
Expand All @@ -169,133 +170,24 @@ def processParameterLine(self, line):
self.name = self.i18n_name = tokens[0]
return

if tokens[1].lower().strip().startswith('output'):
outToken = tokens[1].strip()[len('output') + 1:]
out = self.processOutputParameterToken(outToken)

elif tokens[1].lower().strip().startswith('optional'):
optToken = tokens[1].strip()[len('optional') + 1:]
param = self.processInputParameterToken(optToken, tokens[0])
if param:
param.optional = True

else:
param = self.processInputParameterToken(tokens[1], tokens[0])
out = getOutputFromString(line)
if out is None:
param = getParameterFromString(line)

if param is not None:
self.addParameter(param)
elif out is not None:
out.name = tokens[0]
out.description = tokens[0]
out.description = desc
self.addOutput(out)
else:
raise WrongScriptException(
self.tr('Could not load R script: %s.\n Problem with line %s' % (self.descriptionFile, line)))

def processInputParameterToken(self, token, name):
param = None

desc = self.createDescriptiveName(name)

if token.lower().strip().startswith('raster'):
param = ParameterRaster(name, desc, False)
elif token.lower().strip() == 'vector':
param = ParameterVector(name, desc,
[dataobjects.TYPE_VECTOR_ANY])
elif token.lower().strip() == 'vector point':
param = ParameterVector(name, desc,
[dataobjects.TYPE_VECTOR_POINT])
elif token.lower().strip() == 'vector line':
param = ParameterVector(name, desc,
[dataobjects.TYPE_VECTOR_LINE])
elif token.lower().strip() == 'vector polygon':
param = ParameterVector(name, desc,
[dataobjects.TYPE_VECTOR_POLYGON])
elif token.lower().strip() == 'table':
param = ParameterTable(name, desc, False)
elif token.lower().strip().startswith('multiple raster'):
param = ParameterMultipleInput(name, desc,
dataobjects.TYPE_RASTER)
param.optional = False
elif token.lower().strip() == 'multiple vector':
param = ParameterMultipleInput(name, desc,
dataobjects.TYPE_VECTOR_ANY)
param.optional = False
elif token.lower().strip().startswith('selection'):
options = token.strip()[len('selection'):].split(';')
param = ParameterSelection(name, desc, options)
elif token.lower().strip().startswith('boolean'):
default = token.strip()[len('boolean') + 1:]
if default:
param = ParameterBoolean(name, desc, default)
else:
param = ParameterBoolean(name, desc)
elif token.lower().strip().startswith('number'):
default = token.strip()[len('number') + 1:]
if default:
param = ParameterNumber(name, desc, default=default)
else:
param = ParameterNumber(name, desc)
elif token.lower().strip().startswith('field'):
field = token.strip()[len('field') + 1:]
found = False
for p in self.parameters:
if p.name == field:
found = True
break
if found:
param = ParameterTableField(name, desc, field)
elif token.lower().strip().startswith('multiple field'):
field = token.strip()[len('multiple field') + 1:]
found = False
for p in self.parameters:
if p.name == field:
found = True
break
if found:
param = ParameterTableMultipleField(token, desc, field)
elif token.lower().strip() == 'extent':
param = ParameterExtent(name, desc)
elif token.lower().strip() == 'point':
param = ParameterPoint(name, desc)
elif token.lower().strip() == 'file':
param = ParameterFile(name, desc, False)
elif token.lower().strip() == 'folder':
param = ParameterFile(name, desc, True)
elif token.lower().strip().startswith('string'):
default = token.strip()[len('string') + 1:]
if default:
param = ParameterString(name, desc, default)
else:
param = ParameterString(name, desc)
elif token.lower().strip().startswith('longstring'):
default = token.strip()[len('longstring') + 1:]
if default:
param = ParameterString(name, desc, default, multiline=True)
else:
param = ParameterString(name, desc, multiline=True)
elif token.lower().strip() == 'crs':
default = token.strip()[len('crs') + 1:]
if default:
param = ParameterCrs(name, desc, default)
else:
param = ParameterCrs(name, desc)
self.tr('Could not load script: %s.\n'
'Problem with line "%s"', 'ScriptAlgorithm') % (self.descriptionFile or '', line))

return param

def processOutputParameterToken(self, token):
out = None

if token.lower().strip().startswith('raster'):
out = OutputRaster()
elif token.lower().strip().startswith('vector'):
out = OutputVector()
elif token.lower().strip().startswith('table'):
out = OutputTable()
elif token.lower().strip().startswith('file'):
out = OutputFile()
raise WrongScriptException(
self.tr('Could not load R script: %s.\n Problem with line %s' % (self.descriptionFile, line)))

return out

def processAlgorithm(self, progress):
if isWindows():
Expand Down
53 changes: 46 additions & 7 deletions python/plugins/processing/core/outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,6 @@
from processing.tools import dataobjects


def getOutputFromString(s):
tokens = s.split("|")
params = [t if str(t) != "None" else None for t in tokens[1:]]
clazz = getattr(sys.modules[__name__], tokens[0])
return clazz(*params)


class Output(object):

def __init__(self, name='', description='', hidden=False):
Expand Down Expand Up @@ -351,3 +344,49 @@ def getVectorWriter(self, fields, geomType, crs, options=None):

def dataType(self):
return dataobjects.vectorDataType(self)



def getOutputFromString(s):
try:
if "|" in s:
tokens = s.split("|")
params = [t if unicode(t) != "None" else None for t in tokens[1:]]
clazz = getattr(sys.modules[__name__], tokens[0])
return clazz(*params)
else:
tokens = s.split("=")
token = tokens[1].strip()[len('output') + 1:]
out = None

if token.lower().strip().startswith('raster'):
out = OutputRaster()
elif token.lower().strip() == 'vector':
out = OutputVector()
elif token.lower().strip() == 'vector point':
out = OutputVector(datatype=[dataobjects.TYPE_VECTOR_POINT])
elif token.lower().strip() == 'vector line':
out = OutputVector(datatype=[OutputVector.TYPE_VECTOR_LINE])
elif token.lower().strip() == 'vector polygon':
out = OutputVector(datatype=[OutputVector.TYPE_VECTOR_POLYGON])
elif token.lower().strip().startswith('table'):
out = OutputTable()
elif token.lower().strip().startswith('html'):
out = OutputHTML()
elif token.lower().strip().startswith('file'):
out = OutputFile()
subtokens = token.split(' ')
if len(subtokens) > 2:
out.ext = subtokens[2]
elif token.lower().strip().startswith('directory'):
out = OutputDirectory()
elif token.lower().strip().startswith('number'):
out = OutputNumber()
elif token.lower().strip().startswith('string'):
out = OutputString()
elif token.lower().strip().startswith('extent'):
out = OutputExtent()

return out
except:
return None
8 changes: 6 additions & 2 deletions python/plugins/processing/core/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1360,13 +1360,17 @@ def setValue(self, value):
paramClasses = [c for c in sys.modules[__name__].__dict__.values() if isclass(c) and issubclass(c, Parameter)]

def getParameterFromString(s):
print s
# Try the parameter definitions used in description files
if '|' in s:
isAdvanced = False
if s.startswith("*"):
s = s[1:]
isAdvanced = True
tokens = s.split("|")
params = [t if unicode(t) != unicode(None) else None for t in tokens[1:]]
clazz = getattr(sys.modules[__name__], tokens[0])
return clazz(*params)
param = clazz(*params)
param.isAdvanced = isAdvanced
else: # try script syntax
for paramClass in paramClasses:
try:
Expand Down
73 changes: 3 additions & 70 deletions python/plugins/processing/script/ScriptAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,11 @@
from qgis.PyQt.QtGui import QIcon
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.gui.Help2Html import getHtmlFromHelpFile
from processing.core.parameters import getParameterFromString, paramClasses
from processing.core.outputs import OutputTable
from processing.core.outputs import OutputVector
from processing.core.outputs import OutputRaster
from processing.core.outputs import OutputNumber
from processing.core.outputs import OutputString
from processing.core.outputs import OutputHTML
from processing.core.outputs import OutputFile
from processing.core.outputs import OutputDirectory
from processing.core.parameters import getParameterFromString
from processing.core.outputs import getOutputFromString
from processing.core.ProcessingLog import ProcessingLog
from processing.script.WrongScriptException import WrongScriptException

from processing.tools import dataobjects

pluginPath = os.path.split(os.path.dirname(__file__))[0]


Expand Down Expand Up @@ -128,7 +118,6 @@ def createDescriptiveName(self, s):

def processParameterLine(self, line):
param = None
out = None
line = line.replace('#', '')

if line == "nomodeler":
Expand All @@ -146,10 +135,8 @@ def processParameterLine(self, line):
self.name = self.i18n_name = tokens[0]
return

if tokens[1].lower().strip().startswith('output'):
outToken = tokens[1].strip()[len('output') + 1:]
out = self.processOutputParameterToken(outToken)
else:
out = getOutputFromString(line)
if out is None:
param = getParameterFromString(line)

if param is not None:
Expand All @@ -163,60 +150,6 @@ def processParameterLine(self, line):
self.tr('Could not load script: %s.\n'
'Problem with line "%s"', 'ScriptAlgorithm') % (self.descriptionFile or '', line))

def processInputParameterLine(self, line):
for paramClass in paramClasses:
param = paramClass.fromScriptCode(line)
if param is not None:
return param

def processOutputParameterToken(self, token):
out = None

if token.lower().strip().startswith('raster'):
out = OutputRaster()
elif token.lower().strip() == 'vector':
out = OutputVector()
elif token.lower().strip() == 'vector point':
out = OutputVector(datatype=[dataobjects.TYPE_VECTOR_POINT])
elif token.lower().strip() == 'vector line':
out = OutputVector(datatype=[OutputVector.TYPE_VECTOR_LINE])
elif token.lower().strip() == 'vector polygon':
out = OutputVector(datatype=[OutputVector.TYPE_VECTOR_POLYGON])
elif token.lower().strip().startswith('table'):
out = OutputTable()
elif token.lower().strip().startswith('html'):
out = OutputHTML()
elif token.lower().strip().startswith('file'):
out = OutputFile()
subtokens = token.split(' ')
if len(subtokens) > 2:
out.ext = subtokens[2]
elif token.lower().strip().startswith('directory'):
out = OutputDirectory()
elif token.lower().strip().startswith('number'):
out = OutputNumber()
elif token.lower().strip().startswith('string'):
out = OutputString()
elif token.lower().strip().startswith('extent'):
out = OutputExtent()

return out

def processDescriptionParameterLine(self, line):
try:
if line.startswith('Parameter'):
self.addParameter(getParameterFromString(line))
elif line.startswith('*Parameter'):
param = getParameterFromString(line[1:])
param.isAdvanced = True
self.addParameter(param)
else:
self.addOutput(getOutputFromString(line))
except Exception:
raise WrongScriptException(
self.tr('Could not load script: %s.\n'
'Problem with line %d', 'ScriptAlgorithm') % (self.descriptionFile or '', line))

def processAlgorithm(self, progress):
ns = {}
ns['progress'] = progress
Expand Down

0 comments on commit 01f3808

Please sign in to comment.