def responseComplete(self):
        QgsMessageLog.logMessage("wpsFilter.responseComplete")
        request = self.serverInterface().requestHandler()
        params = request.parameterMap()
        service = params.get('SERVICE', '')
        if service and service.upper() == 'WPS':
            # prepare query
            inputQuery = '&'.join(["%s=%s" % (k, params[k]) for k in params if k.lower() != 'map' and k.lower() != 'config' and k.lower != 'request_body'])
            request_body = params.get('REQUEST_BODY', '')
            
            # get config
            configPath = os.getenv("PYWPS_CFG")
            if not configPath and 'config' in params :
                configPath = params['config']
            elif not configPath and 'CONFIG' in params :
                configPath = params['CONFIG']
            QgsMessageLog.logMessage("configPath "+str(configPath))
            
            if configPath :
                os.environ["PYWPS_CFG"] = configPath
            pywpsConfig.loadConfiguration()
                
            try:
                providerList = ''
                algList = ''
                algsFilter = ''
                if pywpsConfig.config.has_section( 'qgis' ) :
                    # get the providers to publish
                    if pywpsConfig.config.has_option( 'qgis', 'providers' ) :
                        providerList = pywpsConfig.getConfigValue( 'qgis', 'providers' )
                        if providerList :
                            providerList = providerList.split(',')
                    # get the algorithm list to publish
                    if pywpsConfig.config.has_option( 'qgis', 'algs' ) :
                        algList = pywpsConfig.getConfigValue( 'qgis', 'algs' )
                        if algList :
                            algList = algList.split(',')
                    # get the algorithm filter
                    if pywpsConfig.config.has_option( 'qgis', 'algs_filter' ) :
                        algsFilter = pywpsConfig.getConfigValue( 'qgis', 'algs_filter' )
                    
                
                # init Processing
                Processing.initialize()
                # modify processes path and reload algorithms
                if pywpsConfig.config.has_section( 'qgis' ) and pywpsConfig.config.has_option( 'qgis', 'processing_folder' ) :
                    processingPath = pywpsConfig.getConfigValue( 'qgis', 'processing_folder' )
                    if os.path.exists( processingPath ) and os.path.isdir( processingPath ) :
                        ProcessingConfig.setSettingValue( 'MODELS_FOLDER', os.path.join( processingPath, 'models' ) )
                        ProcessingConfig.setSettingValue( 'SCRIPTS_FOLDER', os.path.join( processingPath, 'scripts' ) )
                        ProcessingConfig.setSettingValue( 'R_FOLDER', os.path.join( processingPath, 'rscripts' ) )
                        # Reload algorithms
                        Processing.loadAlgorithms()

                # get QGIS project path
                projectPath = os.getenv("QGIS_PROJECT_FILE")
                if not projectPath and 'map' in params :
                    projectPath = params['map']
                elif not projectPath and 'MAP' in params :
                    projectPath = params['MAP']
                #projectFolder
                projectFolder = ''
                if projectPath and os.path.exists( projectPath ) :
                    projectFolder = os.path.dirname( projectPath )
                QgsMessageLog.logMessage("projectPath "+str(projectPath))
                rasterLayers = []
                vectorLayers = []
                crsList = []
                if projectPath and os.path.exists( projectPath ) :
                    p_dom = minidom.parse( projectPath )
                    for ml in p_dom.getElementsByTagName('maplayer') :
                        l= {'type':ml.attributes["type"].value,
                            'name':ml.getElementsByTagName('layername')[0].childNodes[0].data,
                            'datasource':ml.getElementsByTagName('datasource')[0].childNodes[0].data,
                            'provider':ml.getElementsByTagName('provider')[0].childNodes[0].data,
                            'crs':ml.getElementsByTagName('srs')[0].getElementsByTagName('authid')[0].childNodes[0].data,
                            'proj4':ml.getElementsByTagName('srs')[0].getElementsByTagName('proj4')[0].childNodes[0].data
                        }
                        # Update relative path
                        if l['provider'] in ['ogr','gdal'] and str(l['datasource']).startswith('.'):
                            l['datasource'] = os.path.abspath( os.path.join( projectFolder, l['datasource'] ) )
                            if not os.path.exists( l['datasource'] ) :
                                continue
                        elif l['provider'] in ['gdal'] and str(l['datasource']).startswith('NETCDF:'):
                            theURIParts = l['datasource'].split( ":" );
                            src = theURIParts[1]
                            src = src.replace( '"', '' );
                            if src.startswith('.') :
                                src = os.path.abspath( os.path.join( projectFolder, src ) )
                            theURIParts[1] = '"' + src + '"'
                            l['datasource'] = ':'.join( theURIParts )
                            
                        if l['type'] == "raster" :
                            rasterLayers.append( l )
                        elif l['type'] == "vector" :
                            l['geometry'] = ml.attributes["geometry"].value
                            vectorLayers.append( l )
                    deafultCrs = ''
                    for mapcanvas in p_dom.getElementsByTagName('mapcanvas'):
                        for destinationsrs in mapcanvas.getElementsByTagName('destinationsrs'):
                            for authid in destinationsrs.getElementsByTagName('authid'):
                                defaultCrs = authid.childNodes[0].data
                                crsList.append( defaultCrs )
                    for wmsCrsList in p_dom.getElementsByTagName('WMSCrsList') :
                        for wmsCrs in wmsCrsList.getElementsByTagName('value') :
                            wmsCrsValue = wmsCrs.childNodes[0].data
                            if wmsCrsValue and wmsCrsValue != defaultCrs:
                                crsList.append( wmsCrsValue )
                
                        
                processes = [None] # if no processes found no processes return (deactivate default pywps process)
                identifier = params.get('IDENTIFIER', '').lower()
                for i in Processing.algs :
                    if providerList and i not in providerList :
                        continue
                    QgsMessageLog.logMessage("provider "+i+" "+str(len(Processing.algs[i])))
                    for m in Processing.algs[i]:
                        if identifier and identifier != m :
                            continue
                        if algList and m not in algList :
                            continue
                        if algsFilter :
                            alg = Processing.getAlgorithm( m )
                            if algsFilter.lower() not in alg.name.lower() and algsFilter.lower() not in m.lower():
                                continue
                        #QgsMessageLog.logMessage("provider "+i+" "+m)
                        processes.append(QGISProcessFactory(m, projectPath, vectorLayers, rasterLayers, crsList))
                
                #pywpsConfig.setConfigValue("server","outputPath", '/tmp/wpsoutputs')
                #pywpsConfig.setConfigValue("server","logFile", '/tmp/pywps.log')
                
                qgisaddress = self.serverInterface().getEnv('SERVER_NAME')+self.serverInterface().getEnv('SCRIPT_NAME')
                if self.serverInterface().getEnv('HTTPS') :
                    qgisaddress = 'https://'+qgisaddress
                else :
                    qgisaddress = 'http://'+qgisaddress
                qgisaddress = qgisaddress+'?'
                if 'map' in params :
                    qgisaddress = qgisaddress +'map='+ params['map'] +'&'
                elif 'MAP' in params :
                    qgisaddress = qgisaddress +'MAP='+ params['MAP'] +'&'
                if 'config' in params :
                    qgisaddress = qgisaddress +'config='+ params['config'] +'&'
                elif 'CONFIG' in params :
                    qgisaddress = qgisaddress +'CONFIG='+ params['CONFIG'] +'&'
                #pywpsConfig.setConfigValue("wps","serveraddress", qgisaddress)
                #QgsMessageLog.logMessage("qgisaddress "+qgisaddress)
                #pywpsConfig.setConfigValue("qgis","qgisserveraddress", qgisaddress)
                
                # init wps
                method = 'GET'
                if request_body :
                    method = 'POST'
                wps = pywps.Pywps(method)
                
                # create the request file for POST request
                if request_body :
                    tmpPath=pywpsConfig.getConfigValue("server","tempPath")
                    requestFile = open(os.path.join(tmpPath, "request-"+str(wps.UUID)),"w")
                    requestFile.write(str(request_body))
                    requestFile.close()
                    requestFile = open(os.path.join(tmpPath, "request-"+str(wps.UUID)),"r")
                    inputQuery = requestFile
                    
                if wps.parseRequest(inputQuery):
                    response = wps.performRequest(processes=processes)
                    if response:
                        request.clearHeaders()
                        request.clearBody()
                        #request.setHeader('Content-type', 'text/xml')
                        request.setInfoFormat(wps.request.contentType)
                        resp = wps.response
                        if wps.request.contentType == 'application/xml':
                            import re
                            import xml.sax.saxutils as saxutils
                            resp = re.sub(r'Get xlink:href=".*"', 'Get xlink:href="'+saxutils.escape(qgisaddress)+'"', resp)
                            resp = re.sub(r'Post xlink:href=".*"', 'Post xlink:href="'+saxutils.escape(qgisaddress)+'"', resp)
                        # test response type
                        if isinstance( resp, str ):
                            request.appendBody(resp)
                        elif isinstance( resp, file ) :
                            request.appendBody(resp.read())
            except WPSException,e:
                        request.clearHeaders()
                        #request.setHeader('Content-type', 'text/xml')
                        request.clearBody()
                        request.setInfoFormat('text/xml')
                        request.appendBody(e.__str__())
Exemple #2
0
    def responseComplete(self):
        QgsMessageLog.logMessage("wpsFilter.responseComplete")
        request = self.serverInterface().requestHandler()
        params = request.parameterMap()
        service = params.get('SERVICE', '')
        if service and service.upper() == 'WPS':
            # prepare query
            inputQuery = '&'.join([
                "%s=%s" % (k, params[k]) for k in params if k.lower() != 'map'
                and k.lower() != 'config' and k.lower != 'request_body'
            ])
            request_body = params.get('REQUEST_BODY', '')

            # get config
            configPath = os.getenv("PYWPS_CFG")
            if not configPath and 'config' in params:
                configPath = params['config']
            elif not configPath and 'CONFIG' in params:
                configPath = params['CONFIG']
            QgsMessageLog.logMessage("configPath " + str(configPath))

            if configPath:
                os.environ["PYWPS_CFG"] = configPath
            pywpsConfig.loadConfiguration()

            try:
                providerList = ''
                algList = ''
                algsFilter = ''
                if pywpsConfig.config.has_section('qgis'):
                    # get the providers to publish
                    if pywpsConfig.config.has_option('qgis', 'providers'):
                        providerList = pywpsConfig.getConfigValue(
                            'qgis', 'providers')
                        if providerList:
                            providerList = providerList.split(',')
                    # get the algorithm list to publish
                    if pywpsConfig.config.has_option('qgis', 'algs'):
                        algList = pywpsConfig.getConfigValue('qgis', 'algs')
                        if algList:
                            algList = algList.split(',')
                    # get the algorithm filter
                    if pywpsConfig.config.has_option('qgis', 'algs_filter'):
                        algsFilter = pywpsConfig.getConfigValue(
                            'qgis', 'algs_filter')

                # init Processing
                Processing.initialize()
                # load QGIS Processing config
                if pywpsConfig.config.has_section('qgis_processing'):
                    for opt in pywpsConfig.config.options('qgis_processing'):
                        opt_val = pywpsConfig.getConfigValue(
                            'qgis_processing', opt)
                        ProcessingConfig.setSettingValue(opt.upper(), opt_val)
                    # Reload algorithms
                    Processing.loadAlgorithms()
                # modify processes path and reload algorithms
                if pywpsConfig.config.has_section(
                        'qgis') and pywpsConfig.config.has_option(
                            'qgis', 'processing_folder'):
                    processingPath = pywpsConfig.getConfigValue(
                        'qgis', 'processing_folder')
                    if not os.path.exists(processingPath):
                        if configPath and os.path.exists(configPath):
                            processingPath = os.path.join(
                                os.path.dirname(configPath), processingPath)
                            processingPath = os.path.abspath(processingPath)
                        else:
                            configFilesLocation = pywpsConfig._getDefaultConfigFilesLocation(
                            )
                            for configFileLocation in configFilesLocation:
                                if os.path.exists(configFileLocation):
                                    processingPath = os.path.join(
                                        os.path.dirname(configFileLocation),
                                        processingPath)
                                    processingPath = os.path.abspath(
                                        processingPath)
                    QgsMessageLog.logMessage("processing_folder: " +
                                             processingPath)
                    if os.path.exists(processingPath) and os.path.isdir(
                            processingPath):
                        ProcessingConfig.setSettingValue(
                            'MODELS_FOLDER',
                            os.path.join(processingPath, 'models'))
                        ProcessingConfig.setSettingValue(
                            'SCRIPTS_FOLDER',
                            os.path.join(processingPath, 'scripts'))
                        ProcessingConfig.setSettingValue(
                            'R_SCRIPTS_FOLDER',
                            os.path.join(processingPath, 'rscripts'))
                        # Reload algorithms
                        Processing.loadAlgorithms()

                crsList = []
                if pywpsConfig.config.has_section(
                        'qgis') and pywpsConfig.config.has_option(
                            'qgis', 'input_bbox_crss'):
                    inputBBoxCRSs = pywpsConfig.getConfigValue(
                        'qgis', 'input_bbox_crss')
                    inputBBoxCRSs = inputBBoxCRSs.split(',')
                    crsList = [proj.strip().upper() for proj in inputBBoxCRSs]

                # get QGIS project path
                projectPath = os.getenv("QGIS_PROJECT_FILE")
                if not projectPath and 'map' in params:
                    projectPath = params['map']
                elif not projectPath and 'MAP' in params:
                    projectPath = params['MAP']
                #projectFolder
                projectFolder = ''
                if projectPath and os.path.exists(projectPath):
                    projectFolder = os.path.dirname(projectPath)
                QgsMessageLog.logMessage("projectPath " + str(projectPath))

                rasterLayers = []
                vectorLayers = []

                if projectPath and os.path.exists(projectPath):
                    p_dom = minidom.parse(projectPath)
                    for ml in p_dom.getElementsByTagName('maplayer'):
                        l = {
                            'type':
                            ml.attributes["type"].value,
                            'name':
                            ml.getElementsByTagName(
                                'layername')[0].childNodes[0].data,
                            'datasource':
                            ml.getElementsByTagName(
                                'datasource')[0].childNodes[0].data,
                            'provider':
                            ml.getElementsByTagName(
                                'provider')[0].childNodes[0].data,
                            'crs':
                            ml.getElementsByTagName(
                                'srs')[0].getElementsByTagName(
                                    'authid')[0].childNodes[0].data,
                            'proj4':
                            ml.getElementsByTagName('srs')[0].
                            getElementsByTagName('proj4')[0].childNodes[0].data
                        }
                        # Update relative path
                        if l['provider'] in ['ogr', 'gdal'] and str(
                                l['datasource']).startswith('.'):
                            l['datasource'] = os.path.abspath(
                                os.path.join(projectFolder, l['datasource']))
                            if not os.path.exists(l['datasource']):
                                continue
                        elif l['provider'] in ['gdal'] and str(
                                l['datasource']).startswith('NETCDF:'):
                            theURIParts = l['datasource'].split(":")
                            src = theURIParts[1]
                            src = src.replace('"', '')
                            if src.startswith('.'):
                                src = os.path.abspath(
                                    os.path.join(projectFolder, src))
                            theURIParts[1] = '"' + src + '"'
                            l['datasource'] = ':'.join(theURIParts)

                        if l['type'] == "raster":
                            rasterLayers.append(l)
                        elif l['type'] == "vector":
                            l['geometry'] = ml.attributes["geometry"].value
                            vectorLayers.append(l)

                    deafultCrs = ''
                    for mapcanvas in p_dom.getElementsByTagName('mapcanvas'):
                        for destinationsrs in mapcanvas.getElementsByTagName(
                                'destinationsrs'):
                            for authid in destinationsrs.getElementsByTagName(
                                    'authid'):
                                defaultCrs = authid.childNodes[0].data
                                crsList.append(defaultCrs)
                    for wmsCrsList in p_dom.getElementsByTagName('WMSCrsList'):
                        for wmsCrs in wmsCrsList.getElementsByTagName('value'):
                            wmsCrsValue = wmsCrs.childNodes[0].data
                            if wmsCrsValue and wmsCrsValue != defaultCrs:
                                crsList.append(wmsCrsValue)

                processes = [
                    None
                ]  # if no processes found no processes return (deactivate default pywps process)
                identifier = params.get('IDENTIFIER', '').lower()
                for i in Processing.algs:
                    if providerList and i not in providerList:
                        continue
                    QgsMessageLog.logMessage("provider " + i + " " +
                                             str(len(Processing.algs[i])))
                    for m in Processing.algs[i]:
                        if identifier and identifier != m:
                            continue
                        if algList and m not in algList:
                            continue
                        if algsFilter:
                            alg = Processing.getAlgorithm(m)
                            if algsFilter.lower() not in alg.name.lower(
                            ) and algsFilter.lower() not in m.lower():
                                continue
                        QgsMessageLog.logMessage("provider " + i + " " + m)
                        processes.append(
                            QGISProcessFactory(m, projectPath, vectorLayers,
                                               rasterLayers, crsList))

                #pywpsConfig.setConfigValue("server","outputPath", '/tmp/wpsoutputs')
                #pywpsConfig.setConfigValue("server","logFile", '/tmp/pywps.log')

                qgisaddress = self.serverInterface().getEnv(
                    'SERVER_NAME') + self.serverInterface().getEnv(
                        'SCRIPT_NAME')
                if self.serverInterface().getEnv('HTTPS'):
                    qgisaddress = 'https://' + qgisaddress
                else:
                    qgisaddress = 'http://' + qgisaddress
                qgisaddress = qgisaddress + '?'
                if 'map' in params:
                    qgisaddress = qgisaddress + 'map=' + params['map'] + '&'
                elif 'MAP' in params:
                    qgisaddress = qgisaddress + 'MAP=' + params['MAP'] + '&'
                if 'config' in params:
                    qgisaddress = qgisaddress + 'config=' + params[
                        'config'] + '&'
                elif 'CONFIG' in params:
                    qgisaddress = qgisaddress + 'CONFIG=' + params[
                        'CONFIG'] + '&'
                #pywpsConfig.setConfigValue("wps","serveraddress", qgisaddress)
                QgsMessageLog.logMessage("qgisaddress " + qgisaddress)
                #pywpsConfig.setConfigValue("qgis","qgisserveraddress", qgisaddress)

                # init wps
                method = 'GET'
                if request_body:
                    method = 'POST'
                QgsMessageLog.logMessage("method " + method)
                wps = pywps.Pywps(method)

                # create the request file for POST request
                if request_body:
                    tmpPath = pywpsConfig.getConfigValue("server", "tempPath")
                    requestFile = open(
                        os.path.join(tmpPath, "request-" + str(wps.UUID)), "w")
                    requestFile.write(str(request_body))
                    requestFile.close()
                    requestFile = open(
                        os.path.join(tmpPath, "request-" + str(wps.UUID)), "r")
                    inputQuery = requestFile

                if wps.parseRequest(inputQuery):
                    try:
                        response = wps.performRequest(processes=processes)
                        if response:
                            request.clearHeaders()
                            request.clearBody()
                            #request.setHeader('Content-type', 'text/xml')
                            QgsMessageLog.logMessage("contentType " +
                                                     wps.request.contentType)
                            request.setInfoFormat(wps.request.contentType)
                            resp = wps.response
                            if not pywpsConfig.getConfigValue(
                                    "wps", "serveraddress"
                            ) and wps.request.contentType == 'application/xml':
                                import re
                                import xml.sax.saxutils as saxutils
                                resp = re.sub(
                                    r'Get xlink:href=".*"',
                                    'Get xlink:href="' +
                                    saxutils.escape(qgisaddress) + '"', resp)
                                resp = re.sub(
                                    r'Post xlink:href=".*"',
                                    'Post xlink:href="' +
                                    saxutils.escape(qgisaddress) + '"', resp)
                            elif pywpsConfig.getConfigValue(
                                    "wps", "serveraddress"
                            ) and wps.request.contentType == 'application/xml':
                                import re
                                m = re.search(r'Get xlink:href="(.*)"', resp)
                                if m and m.group(1).count('?') == 2:
                                    import xml.sax.saxutils as saxutils
                                    resp = re.sub(
                                        r'Get xlink:href=".*"',
                                        'Get xlink:href="' + m.group(1)[:-1] +
                                        saxutils.escape('&') + '"', resp)
                            # test response type
                            if isinstance(resp, file):
                                request.appendBody(resp.read())
                            else:
                                request.appendBody(resp)
                        else:
                            QgsMessageLog.logMessage("no response")
                    except:
                        QgsMessageLog.logMessage("Exception perform request")
                else:
                    QgsMessageLog.logMessage("parseRequest False")
            except WPSException as e:
                QgsMessageLog.logMessage("WPSException: " + str(e))
                request.clearHeaders()
                #request.setHeader('Content-type', 'text/xml')
                request.clearBody()
                request.setInfoFormat('text/xml')
                request.appendBody(str(e))
            except Exception as e:
                QgsMessageLog.logMessage("Exception: " + str(e))
                request.clearHeaders()
                #request.setHeader('Content-type', 'text/xml')
                request.clearBody()
                request.setInfoFormat('text/xml')
                request.appendBody(str(e))
from processing.core.ProcessingConfig import ProcessingConfig, Setting
from processing.core.parameters import *
from processing.tools.general import *

cmd_folder = os.path.split(inspect.getfile(inspect.currentframe()))[0]
if cmd_folder not in sys.path:
    sys.path.insert(0, cmd_folder)
Processing.initialize()

# load QGIS Processing config
for opt in config.config.options( 'qgis_processing' ):
    opt_val = config.getConfigValue( 'qgis_processing', opt )
    ProcessingConfig.setSettingValue( opt.upper(), opt_val )

# Relaod algorithms
Processing.loadAlgorithms()


def QGISProcessFactory(alg_name):
    """This is the bridge between QGIS Processing and PyWPS:
    it creates PyWPS processes based on QGIS Processing alg name
    it is inspired by Alessandro Pasotti work
    """
    from pywps.Process import WPSProcess
    from new import classobj
    import types
    from processing.core.Processing import Processing
    # Sanitize name
    class_name = alg_name.replace(':', '_')
    alg = Processing.getAlgorithm(alg_name)