194 lines
6.5 KiB
Python
Raw Normal View History

2012-10-05 23:28:47 +02:00
# -*- coding: utf-8 -*-
"""
***************************************************************************
RUtils.py
---------------------
Date : August 2012
Copyright : (C) 2012 by Victor Olaya
Email : volayaf at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
2012-10-05 23:28:47 +02:00
# This will get replaced with a git SHA1 when you do a git archive
2012-10-05 23:28:47 +02:00
__revision__ = '$Format:%H$'
import re
import os
import stat
import subprocess
2012-09-15 18:25:25 +03:00
from PyQt4.QtGui import *
from PyQt4.QtCore import *
2013-08-12 20:44:27 +02:00
from processing.core.ProcessingConfig import ProcessingConfig
from processing.core.ProcessingLog import ProcessingLog
from processing.tools.system import *
2012-09-15 18:25:25 +03:00
class RUtils:
RSCRIPTS_FOLDER = 'R_SCRIPTS_FOLDER'
R_FOLDER = 'R_FOLDER'
R_USE64 = 'R_USE64'
2012-09-15 18:25:25 +03:00
@staticmethod
def RFolder():
2013-08-12 20:44:27 +02:00
folder = ProcessingConfig.getSetting(RUtils.R_FOLDER)
if folder is None:
folder = ''
2012-09-15 18:25:25 +03:00
return os.path.abspath(unicode(folder))
2012-09-15 18:25:25 +03:00
@staticmethod
def RScriptsFolder():
2013-08-12 20:44:27 +02:00
folder = ProcessingConfig.getSetting(RUtils.RSCRIPTS_FOLDER)
if folder is None:
folder = unicode(os.path.join(userFolder(), 'rscripts'))
2012-09-15 18:25:25 +03:00
mkdir(folder)
return os.path.abspath(folder)
2012-09-15 18:25:25 +03:00
@staticmethod
def createRScriptFromRCommands(commands):
scriptfile = open(RUtils.getRScriptFilename(), 'w')
2012-09-15 18:25:25 +03:00
for command in commands:
scriptfile.write(command + '\n')
2012-09-15 18:25:25 +03:00
scriptfile.close()
@staticmethod
def getRScriptFilename():
return userFolder() + os.sep + 'processing_script.r'
2012-09-15 18:25:25 +03:00
@staticmethod
def getConsoleOutputFilename():
return RUtils.getRScriptFilename() + '.Rout'
2012-09-15 18:25:25 +03:00
@staticmethod
def executeRAlgorithm(alg, progress):
RUtils.verboseCommands = alg.getVerboseCommands()
2012-09-15 18:25:25 +03:00
RUtils.createRScriptFromRCommands(alg.getFullSetOfRCommands())
if isWindows():
2013-08-12 20:44:27 +02:00
if ProcessingConfig.getSetting(RUtils.R_USE64):
execDir = 'x64'
2013-02-23 15:44:44 +01:00
else:
execDir = 'i386'
command = [
RUtils.RFolder() + os.sep + 'bin' + os.sep + execDir + os.sep
+ 'R.exe',
'CMD',
'BATCH',
'--vanilla',
RUtils.getRScriptFilename(),
RUtils.getConsoleOutputFilename(),
]
2012-09-15 18:25:25 +03:00
else:
os.chmod(RUtils.getRScriptFilename(), stat.S_IEXEC | stat.S_IREAD
| stat.S_IWRITE)
command = 'R CMD BATCH --vanilla ' + RUtils.getRScriptFilename() \
+ ' ' + RUtils.getConsoleOutputFilename()
proc = subprocess.Popen(
command,
shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
)
2012-09-15 18:25:25 +03:00
proc.wait()
RUtils.createConsoleOutput()
loglines = []
loglines.append('R execution console output')
2012-09-15 18:25:25 +03:00
loglines += RUtils.allConsoleResults
for line in loglines:
progress.setConsoleInfo(line)
2013-08-12 20:44:27 +02:00
ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)
2012-09-15 18:25:25 +03:00
@staticmethod
def createConsoleOutput():
RUtils.consoleResults = []
RUtils.allConsoleResults = []
add = False
if os.path.exists(RUtils.getConsoleOutputFilename()):
lines = open(RUtils.getConsoleOutputFilename())
for line in lines:
line = line.strip('\n').strip(' ')
if line.startswith('>'):
line = line[1:].strip(' ')
2012-09-15 18:25:25 +03:00
if line in RUtils.verboseCommands:
add = True
else:
add = False
elif add:
RUtils.consoleResults.append('<p>' + line + '</p>\n')
RUtils.allConsoleResults.append(line)
2012-09-15 18:25:25 +03:00
@staticmethod
def getConsoleOutput():
s = '<font face="courier">\n'
s += '<h2> R Output</h2>\n'
2012-09-15 18:25:25 +03:00
for line in RUtils.consoleResults:
s += line
s += '</font>\n'
2012-09-15 18:25:25 +03:00
return s
2013-07-21 21:53:27 +02:00
@staticmethod
def checkRIsInstalled(ignoreRegistrySettings=False):
if 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 isWindows():
2013-08-12 20:44:27 +02:00
if ProcessingConfig.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/en/docs/user_manual/processing/3rdParty.html">Click here</a>to know more about how to install and configure R to be used with QGIS</p>'
return html
2013-07-21 21:53:27 +02:00
@staticmethod
def getRequiredPackages(code):
regex = re.compile('library\("?(.*?)"?\)')
return regex.findall(code)