processing: when using batch jobs remove GISBASE from environment when calling GRASS (fixes #13072)

This commit is contained in:
Juergen E. Fischer 2015-08-20 01:10:43 +02:00
parent 16d7a0659e
commit d2282a77c7
3 changed files with 41 additions and 38 deletions

View File

@ -30,12 +30,11 @@ import shutil
import codecs import codecs
import subprocess import subprocess
import os import os
from qgis.core import QgsApplication from qgis.core import QgsApplication
from PyQt4.QtCore import QCoreApplication from PyQt4.QtCore import QCoreApplication
from processing.core.ProcessingConfig import ProcessingConfig from processing.core.ProcessingConfig import ProcessingConfig
from processing.core.ProcessingLog import ProcessingLog from processing.core.ProcessingLog import ProcessingLog
from processing.tools.system import userFolder, isMac, isWindows, mkdir, tempFolder from processing.tools.system import userFolder, isWindows, isMac, tempFolder, mkdir
from processing.tests.TestData import points from processing.tests.TestData import points
@ -150,8 +149,7 @@ class GrassUtils:
output.write('if "%GRASS_ADDON_PATH%"=="" set PATH=%WINGISBASE%\\bin;%WINGISBASE%\\lib;%PATH%\n') output.write('if "%GRASS_ADDON_PATH%"=="" set PATH=%WINGISBASE%\\bin;%WINGISBASE%\\lib;%PATH%\n')
output.write('if not "%GRASS_ADDON_PATH%"=="" set PATH=%WINGISBASE%\\bin;%WINGISBASE%\\lib;%GRASS_ADDON_PATH%;%PATH%\n') output.write('if not "%GRASS_ADDON_PATH%"=="" set PATH=%WINGISBASE%\\bin;%WINGISBASE%\\lib;%GRASS_ADDON_PATH%;%PATH%\n')
output.write('\n') output.write('\n')
output.write('set GRASS_VERSION=' + GrassUtils.getGrassVersion() output.write('set GRASS_VERSION=' + GrassUtils.getGrassVersion() + '\n')
+ '\n')
output.write('if not "%LANG%"=="" goto langset\n') output.write('if not "%LANG%"=="" goto langset\n')
output.write('FOR /F "usebackq delims==" %%i IN (`"%WINGISBASE%\\etc\\winlocale"`) DO @set LANG=%%i\n') output.write('FOR /F "usebackq delims==" %%i IN (`"%WINGISBASE%\\etc\\winlocale"`) DO @set LANG=%%i\n')
output.write(':langset\n') output.write(':langset\n')
@ -203,12 +201,12 @@ class GrassUtils:
folder = GrassUtils.grassMapsetFolder() folder = GrassUtils.grassMapsetFolder()
mkdir(os.path.join(folder, 'PERMANENT')) mkdir(os.path.join(folder, 'PERMANENT'))
mkdir(os.path.join(folder, 'PERMANENT', '.tmp')) mkdir(os.path.join(folder, 'PERMANENT', '.tmp'))
GrassUtils.writeGrassWindow(os.path.join(folder, 'PERMANENT', GrassUtils.writeGrassWindow(os.path.join(folder, 'PERMANENT', 'DEFAULT_WIND'))
'DEFAULT_WIND'))
outfile = codecs.open(os.path.join(folder, 'PERMANENT', 'MYNAME'), 'w', encoding='utf-8') outfile = codecs.open(os.path.join(folder, 'PERMANENT', 'MYNAME'), 'w', encoding='utf-8')
outfile.write( outfile.write(
'QGIS GRASS interface: temporary data processing location.\n') 'QGIS GRASS interface: temporary data processing location.\n')
outfile.close() outfile.close()
GrassUtils.writeGrassWindow(os.path.join(folder, 'PERMANENT', 'WIND')) GrassUtils.writeGrassWindow(os.path.join(folder, 'PERMANENT', 'WIND'))
mkdir(os.path.join(folder, 'PERMANENT', 'dbf')) mkdir(os.path.join(folder, 'PERMANENT', 'dbf'))
outfile = codecs.open(os.path.join(folder, 'PERMANENT', 'VAR'), 'w', encoding='utf-8') outfile = codecs.open(os.path.join(folder, 'PERMANENT', 'VAR'), 'w', encoding='utf-8')
@ -242,14 +240,17 @@ class GrassUtils:
@staticmethod @staticmethod
def prepareGrassExecution(commands): def prepareGrassExecution(commands):
env = os.environ.copy()
if isWindows(): if isWindows():
GrassUtils.createGrassScript(commands) GrassUtils.createGrassScript(commands)
command = ['cmd.exe', '/C ', GrassUtils.grassScriptFilename()] command = ['cmd.exe', '/C ', GrassUtils.grassScriptFilename()]
else: else:
gisrc = userFolder() + os.sep + 'processing.gisrc' gisrc = userFolder() + os.sep + 'processing.gisrc'
os.putenv('GISRC', gisrc) env['GISRC'] = gisrc
os.putenv('GRASS_MESSAGE_FORMAT', 'gui') env['GRASS_MESSAGE_FORMAT'] = 'gui'
os.putenv('GRASS_BATCH_JOB', GrassUtils.grassBatchJobFilename()) env['GRASS_BATCH_JOB'] = GrassUtils.grassBatchJobFilename()
del env['GISBASE']
GrassUtils.createGrassBatchJobFileFromGrassCommands(commands) GrassUtils.createGrassBatchJobFileFromGrassCommands(commands)
os.chmod(GrassUtils.grassBatchJobFilename(), stat.S_IEXEC os.chmod(GrassUtils.grassBatchJobFilename(), stat.S_IEXEC
| stat.S_IREAD | stat.S_IWRITE) | stat.S_IREAD | stat.S_IWRITE)
@ -260,14 +261,14 @@ class GrassUtils:
command = 'grass64 ' + GrassUtils.grassMapsetFolder() \ command = 'grass64 ' + GrassUtils.grassMapsetFolder() \
+ '/PERMANENT' + '/PERMANENT'
return command return command, env
@staticmethod @staticmethod
def executeGrass(commands, progress, outputCommands=None): def executeGrass(commands, progress, outputCommands=None):
loglines = [] loglines = []
loglines.append('GRASS execution console output') loglines.append('GRASS execution console output')
grassOutDone = False grassOutDone = False
command = GrassUtils.prepareGrassExecution(commands) command, grassenv = GrassUtils.prepareGrassExecution(commands)
proc = subprocess.Popen( proc = subprocess.Popen(
command, command,
shell=True, shell=True,
@ -275,13 +276,13 @@ class GrassUtils:
stdin=open(os.devnull), stdin=open(os.devnull),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
universal_newlines=True, universal_newlines=True,
env=grassenv
).stdout ).stdout
progress.setInfo('GRASS commands output:') progress.setInfo('GRASS commands output:')
for line in iter(proc.readline, ''): for line in iter(proc.readline, ''):
if 'GRASS_INFO_PERCENT' in line: if 'GRASS_INFO_PERCENT' in line:
try: try:
progress.setPercentage(int(line[len('GRASS_INFO_PERCENT') progress.setPercentage(int(line[len('GRASS_INFO_PERCENT') + 2:]))
+ 2:]))
except: except:
pass pass
else: else:
@ -297,7 +298,7 @@ class GrassUtils:
# commands again. # commands again.
if not grassOutDone and outputCommands: if not grassOutDone and outputCommands:
command = GrassUtils.prepareGrassExecution(outputCommands) command, grassenv = GrassUtils.prepareGrassExecution(outputCommands)
proc = subprocess.Popen( proc = subprocess.Popen(
command, command,
shell=True, shell=True,
@ -305,6 +306,7 @@ class GrassUtils:
stdin=open(os.devnull), stdin=open(os.devnull),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
universal_newlines=True, universal_newlines=True,
env=grassenv
).stdout ).stdout
for line in iter(proc.readline, ''): for line in iter(proc.readline, ''):
if 'GRASS_INFO_PERCENT' in line: if 'GRASS_INFO_PERCENT' in line:
@ -320,8 +322,6 @@ class GrassUtils:
if ProcessingConfig.getSetting(GrassUtils.GRASS_LOG_CONSOLE): if ProcessingConfig.getSetting(GrassUtils.GRASS_LOG_CONSOLE):
ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)
# GRASS session is used to hold the layers already exported or # GRASS session is used to hold the layers already exported or
# produced in GRASS between multiple calls to GRASS algorithms. # produced in GRASS between multiple calls to GRASS algorithms.
# This way they don't have to be loaded multiple times and # This way they don't have to be loaded multiple times and
@ -349,8 +349,9 @@ class GrassUtils:
@staticmethod @staticmethod
def addSessionLayers(exportedLayers): def addSessionLayers(exportedLayers):
GrassUtils.sessionLayers = dict(GrassUtils.sessionLayers.items() GrassUtils.sessionLayers = dict(
+ exportedLayers.items()) GrassUtils.sessionLayers.items()
+ exportedLayers.items())
@staticmethod @staticmethod
def checkGrassIsInstalled(ignorePreviousState=False): def checkGrassIsInstalled(ignorePreviousState=False):

View File

@ -95,8 +95,7 @@ class Grass7Utils:
folder = os.path.join(testfolder, subfolder) folder = os.path.join(testfolder, subfolder)
break break
else: else:
folder = os.path.join(unicode(QgsApplication.prefixPath()), 'grass7' folder = os.path.join(unicode(QgsApplication.prefixPath()), 'grass7')
)
if not os.path.isdir(folder): if not os.path.isdir(folder):
folder = '/Applications/GRASS-7.0.app/Contents/MacOS' folder = '/Applications/GRASS-7.0.app/Contents/MacOS'
@ -240,14 +239,17 @@ class Grass7Utils:
@staticmethod @staticmethod
def prepareGrass7Execution(commands): def prepareGrass7Execution(commands):
env = os.environ.copy()
if isWindows(): if isWindows():
Grass7Utils.createGrass7Script(commands) Grass7Utils.createGrass7Script(commands)
command = ['cmd.exe', '/C ', Grass7Utils.grassScriptFilename()] command = ['cmd.exe', '/C ', Grass7Utils.grassScriptFilename()]
else: else:
gisrc = userFolder() + os.sep + 'processing.gisrc7' gisrc = userFolder() + os.sep + 'processing.gisrc7'
os.putenv('GISRC', gisrc) env['GISRC'] = gisrc
os.putenv('GRASS_MESSAGE_FORMAT', 'gui') env['GRASS_MESSAGE_FORMAT'] = 'gui'
os.putenv('GRASS_BATCH_JOB', Grass7Utils.grassBatchJobFilename()) env['GRASS_BATCH_JOB'] = Grass7Utils.grassBatchJobFilename()
del env['GISBASE']
Grass7Utils.createGrass7BatchJobFileFromGrass7Commands(commands) Grass7Utils.createGrass7BatchJobFileFromGrass7Commands(commands)
os.chmod(Grass7Utils.grassBatchJobFilename(), stat.S_IEXEC os.chmod(Grass7Utils.grassBatchJobFilename(), stat.S_IEXEC
| stat.S_IREAD | stat.S_IWRITE) | stat.S_IREAD | stat.S_IWRITE)
@ -258,14 +260,14 @@ class Grass7Utils:
command = 'grass70 ' + Grass7Utils.grassMapsetFolder() \ command = 'grass70 ' + Grass7Utils.grassMapsetFolder() \
+ '/PERMANENT' + '/PERMANENT'
return command return command, env
@staticmethod @staticmethod
def executeGrass7(commands, progress, outputCommands=None): def executeGrass7(commands, progress, outputCommands=None):
loglines = [] loglines = []
loglines.append(Grass7Utils.tr('GRASS GIS 7 execution console output')) loglines.append(Grass7Utils.tr('GRASS GIS 7 execution console output'))
grassOutDone = False grassOutDone = False
command = Grass7Utils.prepareGrass7Execution(commands) command, grassenv = Grass7Utils.prepareGrass7Execution(commands)
proc = subprocess.Popen( proc = subprocess.Popen(
command, command,
shell=True, shell=True,
@ -273,6 +275,7 @@ class Grass7Utils:
stdin=open(os.devnull), stdin=open(os.devnull),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
universal_newlines=True, universal_newlines=True,
env=grassenv
).stdout ).stdout
for line in iter(proc.readline, ''): for line in iter(proc.readline, ''):
if 'GRASS_INFO_PERCENT' in line: if 'GRASS_INFO_PERCENT' in line:
@ -293,7 +296,7 @@ class Grass7Utils:
# commands again. # commands again.
if not grassOutDone and outputCommands: if not grassOutDone and outputCommands:
command = Grass7Utils.prepareGrass7Execution(outputCommands) command, grassenv = Grass7Utils.prepareGrass7Execution(outputCommands)
proc = subprocess.Popen( proc = subprocess.Popen(
command, command,
shell=True, shell=True,
@ -301,6 +304,7 @@ class Grass7Utils:
stdin=open(os.devnull), stdin=open(os.devnull),
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
universal_newlines=True, universal_newlines=True,
env=grassenv
).stdout ).stdout
for line in iter(proc.readline, ''): for line in iter(proc.readline, ''):
if 'GRASS_INFO_PERCENT' in line: if 'GRASS_INFO_PERCENT' in line:

View File

@ -31,6 +31,7 @@ from PyQt4.QtCore import Qt, QCoreApplication
from PyQt4.QtGui import QApplication, QCursor from PyQt4.QtGui import QApplication, QCursor
from qgis.utils import iface from qgis.utils import iface
from qgis.core import QgsMessageLog
import processing import processing
from processing.gui import AlgorithmClassification from processing.gui import AlgorithmClassification
@ -272,7 +273,7 @@ class Processing:
else: else:
alg = Processing.getAlgorithm(algOrName) alg = Processing.getAlgorithm(algOrName)
if alg is None: if alg is None:
print 'Error: Algorithm not found\n' QgsMessageLog.logMessage( Processing.tr( 'Error: Algorithm {0} not found\n' ).format( algOrName ), Processing.tr( "Processing" ) )
return return
alg = alg.getCopy() alg = alg.getCopy()
@ -288,7 +289,7 @@ class Processing:
output = alg.getOutputFromName(name) output = alg.getOutputFromName(name)
if output and output.setValue(value): if output and output.setValue(value):
continue continue
print 'Error: Wrong parameter value %s for parameter %s.' % (value, name) QgsMessageLog.logMessage( Processing.tr( 'Error: Wrong parameter value {0} for parameter {1}.' ).format(value, name), Processing.tr( "Processing" ) )
ProcessingLog.addToLog( ProcessingLog.addToLog(
ProcessingLog.LOG_ERROR, ProcessingLog.LOG_ERROR,
Processing.tr('Error in %s. Wrong parameter value %s for parameter %s.') % ( Processing.tr('Error in %s. Wrong parameter value %s for parameter %s.') % (
@ -299,7 +300,7 @@ class Processing:
for param in alg.parameters: for param in alg.parameters:
if param.name not in setParams: if param.name not in setParams:
if not param.setValue(None): if not param.setValue(None):
print ('Error: Missing parameter value for parameter %s.' % (param.name)) QgsMessageLog.logMessage( Processing.tr( 'Error: Missing parameter value for parameter {0}.' ).format(param.name), Processing.tr( "Processing" ) )
ProcessingLog.addToLog( ProcessingLog.addToLog(
ProcessingLog.LOG_ERROR, ProcessingLog.LOG_ERROR,
Processing.tr('Error in %s. Missing parameter value for parameter %s.') % ( Processing.tr('Error in %s. Missing parameter value for parameter %s.') % (
@ -308,33 +309,31 @@ class Processing:
return return
else: else:
if len(args) != alg.getVisibleParametersCount() + alg.getVisibleOutputsCount(): if len(args) != alg.getVisibleParametersCount() + alg.getVisibleOutputsCount():
print 'Error: Wrong number of parameters' QgsMessageLog.logMessage( Processing.tr( 'Error: Wrong number of parameters' ), Processing.tr( "Processing" ) )
processing.alghelp(algOrName) processing.alghelp(algOrName)
return return
i = 0 i = 0
for param in alg.parameters: for param in alg.parameters:
if not param.hidden: if not param.hidden:
if not param.setValue(args[i]): if not param.setValue(args[i]):
print 'Error: Wrong parameter value: ' \ QgsMessageLog.logMessage( Processing.tr( 'Error: Wrong parameter value: ' ) + unicode(args[i]), Processing.tr( "Processing" ) )
+ unicode(args[i])
return return
i = i + 1 i = i + 1
for output in alg.outputs: for output in alg.outputs:
if not output.hidden: if not output.hidden:
if not output.setValue(args[i]): if not output.setValue(args[i]):
print 'Error: Wrong output value: ' + unicode(args[i]) QgsMessageLog.logMessage( Processing.tr( 'Error: Wrong output value: ' ) + unicode(args[i]), Processing.tr( "Processing" ) )
return return
i = i + 1 i = i + 1
msg = alg._checkParameterValuesBeforeExecuting() msg = alg._checkParameterValuesBeforeExecuting()
if msg: if msg:
print 'Unable to execute algorithm\n' + msg QgsMessageLog( Processing.tr( 'Unable to execute algorithm\n{0}' ).format( msg ), Processing.tr( "Processing" ) )
return return
if not alg.checkInputCRS(): if not alg.checkInputCRS():
print 'Warning: Not all input layers use the same CRS.\n' \ QgsMessageLog( Processing.tr( 'Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.' ), Processing.tr("Processing") )
+ 'This can cause unexpected results.'
if iface is not None: if iface is not None:
# Don't set the wait cursor twice, because then when you # Don't set the wait cursor twice, because then when you
@ -353,8 +352,7 @@ class Processing:
if onFinish is not None: if onFinish is not None:
onFinish(alg, progress) onFinish(alg, progress)
else: else:
print ("There were errors executing the algorithm.\n" QgsMessageLog( Processing.tr( "There were errors executing the algorithm.\nCheck the QGIS log to get more information"), Processing.tr("Processing") )
"Check the QGIS log to get more information")
if iface is not None: if iface is not None:
QApplication.restoreOverrideCursor() QApplication.restoreOverrideCursor()