Skip to content

Commit 35556de

Browse files
committed
Merge pull request #1701 from elpaso/serverpython2
[feature] Serverpython2
2 parents 9491851 + a790f7f commit 35556de

29 files changed

+1200
-21
lines changed

CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ IF(WITH_MAPSERVER)
4646
SET (MAPSERVER_SKIP_ECW FALSE CACHE BOOL "Determines whether QGIS mapserver should disable ECW (ECW in server apps requires a special license)")
4747
ENDIF(WITH_MAPSERVER)
4848

49+
50+
SET (WITH_SERVER_PLUGINS TRUE CACHE BOOL "Determines whether QGIS mapserver support for python plugins should be built")
51+
IF(WITH_SERVER_PLUGINS)
52+
SET(MAPSERVER_HAVE_PYTHON_PLUGINS TRUE)
53+
ENDIF(WITH_SERVER_PLUGINS)
54+
55+
4956
# Custom widgets
5057
SET (WITH_CUSTOM_WIDGETS FALSE CACHE BOOL "Determines whether QGIS custom widgets for Qt Designer should be built")
5158

@@ -76,6 +83,7 @@ IF(WITH_ORACLE)
7683
SET(HAVE_ORACLE TRUE)
7784
ENDIF(WITH_ORACLE)
7885

86+
7987
# try to configure and build python bindings by default
8088
SET (WITH_BINDINGS TRUE CACHE BOOL "Determines whether python bindings should be built")
8189
IF (WITH_BINDINGS)

cmake_templates/qgsconfig.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,7 @@
5656

5757
#cmakedefine MAPSERVER_SKIP_ECW
5858

59+
#cmakedefine MAPSERVER_HAVE_PYTHON_PLUGINS
60+
5961
#endif
6062

python/CMakeLists.txt

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${QGIS_PYTHON_OUTPUT_DIRECTORY})
2222
#
2323
# NOTE: regular project 'make install' is unaffected
2424

25-
# Other target dependenciess will be added, per staged resource
25+
# Other target dependencies will be added, per staged resource
2626
ADD_CUSTOM_TARGET(staged-plugins)
2727

2828
# Plugins can also be staged with CMake option at build time
@@ -163,6 +163,27 @@ ENDIF(UNIX AND NOT SIP_VERSION_NUM LESS 265984)
163163

164164
ADD_SIP_PYTHON_MODULE(qgis._gui gui/gui.sip qgis_core qgis_gui)
165165

166+
SET(PY_MODULES core gui analysis networkanalysis)
167+
168+
# server module
169+
IF (WITH_SERVER_PLUGINS)
170+
INCLUDE_DIRECTORIES(
171+
../src/mapserver
172+
${CMAKE_BINARY_DIR}/src/mapserver
173+
)
174+
175+
SET(PY_MODULES ${PY_MODULES} server)
176+
177+
FILE(GLOB sip_files_server
178+
server/*.sip
179+
)
180+
SET(SIP_EXTRA_FILES_DEPEND ${sip_files_core} ${sip_files_server})
181+
SET(SIP_EXTRA_OPTIONS ${PYQT4_SIP_FLAGS} -o -a ${CMAKE_BINARY_DIR}/python/qgis.server.api)
182+
ADD_SIP_PYTHON_MODULE(qgis._server server/server.sip qgis_core qgis_server)
183+
184+
ENDIF (WITH_SERVER_PLUGINS)
185+
186+
166187
# additional analysis includes
167188
INCLUDE_DIRECTORIES(
168189
../src/analysis/vector
@@ -234,7 +255,7 @@ ENDIF(WITH_CUSTOM_WIDGETS)
234255
# Plugin utilities files to copy to staging or install
235256
SET(PY_FILES
236257
__init__.py
237-
utils.py
258+
utils.py
238259
)
239260

240261
ADD_CUSTOM_TARGET(pyutils ALL)
@@ -251,7 +272,7 @@ FOREACH(pyfile ${PY_FILES})
251272
PY_COMPILE(pyutils "${QGIS_PYTHON_OUTPUT_DIRECTORY}/${pyfile}")
252273
ENDFOREACH(pyfile)
253274

254-
FOREACH(module core gui analysis networkanalysis)
275+
FOREACH(module ${PY_MODULES})
255276
ADD_CUSTOM_TARGET(py${module} ALL)
256277
ADD_DEPENDENCIES(py${module} python_module_qgis__${module})
257278
FILE(GLOB_RECURSE PY_FILES "${module}/*.py")

python/server/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from qgis._server import *
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/***************************************************************************
2+
qgscapabilitiescache.sip
3+
4+
A cache for capabilities xml documents (by configuration file path)
5+
-------------------
6+
begin : 2014-09-10
7+
copyright : (C) 2014 by Alessandro Pasotti
8+
email : a dot pasotti at itopen dot it
9+
***************************************************************************/
10+
11+
/***************************************************************************
12+
* *
13+
* This program is free software; you can redistribute it and/or modify *
14+
* it under the terms of the GNU General Public License as published by *
15+
* the Free Software Foundation; either version 2 of the License, or *
16+
* (at your option) any later version. *
17+
* *
18+
***************************************************************************/
19+
20+
/**
21+
* \class QgsCapabilitiesCache
22+
* \brief A cache for capabilities xml documents (by configuration file path)
23+
*/
24+
class QgsCapabilitiesCache: public QObject
25+
{
26+
%TypeHeaderCode
27+
#include "qgscapabilitiescache.h"
28+
%End
29+
public:
30+
31+
/**Returns cached capabilities document (or 0 if document for configuration file not in cache)*/
32+
const QDomDocument* searchCapabilitiesDocument( QString configFilePath, QString version );
33+
/**Inserts new capabilities document (creates a copy of the document, does not take ownership)*/
34+
void insertCapabilitiesDocument( QString configFilePath, QString version, const QDomDocument* doc );
35+
36+
};
37+
38+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/***************************************************************************
2+
qgsmapserviceexception.sip
3+
4+
QGIS Server exception
5+
-------------------
6+
begin : 2014-09-10
7+
copyright : (C) 2014 by Alessandro Pasotti
8+
email : a dot pasotti at itopen dot it
9+
***************************************************************************/
10+
11+
/***************************************************************************
12+
* *
13+
* This program is free software; you can redistribute it and/or modify *
14+
* it under the terms of the GNU General Public License as published by *
15+
* the Free Software Foundation; either version 2 of the License, or *
16+
* (at your option) any later version. *
17+
* *
18+
***************************************************************************/
19+
20+
21+
/**
22+
* \class QgsMapServiceException
23+
* \brief Exception class for WMS service exceptions.
24+
*
25+
* The most important codes are:
26+
* * "InvalidFormat"
27+
* * "Invalid CRS"
28+
* * "LayerNotDefined" / "StyleNotDefined"
29+
* * "OperationNotSupported"
30+
*/
31+
32+
class QgsMapServiceException
33+
{
34+
%TypeHeaderCode
35+
#include <qgsmapserviceexception.h>
36+
%End
37+
public:
38+
QgsMapServiceException( const QString& code, const QString& message );
39+
QString code() const;
40+
QString message() const;
41+
42+
};

python/server/qgsrequesthandler.sip

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/***************************************************************************
2+
qgsrequesthandler.sip
3+
4+
This class is an interface hiding the details of reading input and
5+
writing output from/to a wms request mechanism
6+
-------------------
7+
begin : 2014-09-10
8+
copyright : (C) 2014 by Alessandro Pasotti
9+
email : a dot pasotti at itopen dot it
10+
***************************************************************************/
11+
12+
13+
/**
14+
* \class QgsRequestHandler
15+
* \brief This class is an interface hiding the details of reading input and
16+
* writing output from/to a wms request mechanism.
17+
*
18+
* Examples of possible mechanisms are cgi Get, cgi Post, SOAP or the usage
19+
* as a standalone command line executable
20+
*/
21+
22+
class QgsRequestHandler
23+
{
24+
%TypeHeaderCode
25+
#include "qgsmapserviceexception.h"
26+
#include "qgsrequesthandler.h"
27+
28+
%End
29+
30+
public:
31+
32+
/**Set an HTTP header*/
33+
virtual void setHeader( const QString &name, const QString &value ) = 0;
34+
/**Remove an HTTP header*/
35+
virtual int removeHeader( const QString &name ) = 0;
36+
/**Delete all HTTP headers*/
37+
virtual void clearHeaders( ) = 0;
38+
/**Returns the response body*/
39+
virtual QByteArray body();
40+
/**Append the bytestream to response body*/
41+
virtual void appendBody( const QByteArray &body) = 0;
42+
/**Clears the response body*/
43+
virtual void clearBody( ) = 0;
44+
/**Set the info format string such as "text/xml"*/
45+
virtual void setInfoFormat( const QString &format ) = 0;
46+
/**Check wether there is any header set or the body is not empty*/
47+
virtual bool responseReady() const = 0;
48+
/**Pointer to last raised exception*/
49+
virtual bool exceptionRaised() const = 0;
50+
/**Return a copy of the parsed parameters as a key-value pair, to modify
51+
* a parameter setParameter( const QString &key, const QString &value)
52+
* and removeParameter(const QString &key) must be used
53+
*/
54+
QMap<QString, QString> parameterMap( );
55+
/**Set a request parameter*/
56+
virtual void setParameter(const QString &key, const QString &value) = 0;
57+
/**Remove a request parameter*/
58+
virtual int removeParameter(const QString &key) = 0;
59+
/**Return a request parameter*/
60+
virtual QString parameter(const QString &key) const = 0;
61+
/**Return the image format*/
62+
QString format() const;
63+
/**Return the format string as requested by the client*/
64+
QString infoFormat() const;
65+
/**Allow plugins to return a QgsMapServiceException*/
66+
virtual void setServiceException( QgsMapServiceException ex /Transfer/) = 0;
67+
68+
private:
69+
70+
/* Not yet part of the API */
71+
72+
virtual void sendHeaders( ) const = 0;
73+
virtual void sendBody( ) const = 0;
74+
75+
/**Send out the response writing to FCGI stdout*/
76+
virtual void sendResponse( ) const = 0;
77+
78+
virtual void parseInput() = 0;
79+
virtual void setGetMapResponse( const QString& service, QImage* img, int imageQuality ) = 0;
80+
virtual void setGetCapabilitiesResponse( const QDomDocument& doc ) = 0;
81+
virtual void setGetFeatureInfoResponse( const QDomDocument& infoDoc, const QString& infoFormat ) = 0;
82+
virtual void setGetStyleResponse( const QDomDocument& doc ) = 0;
83+
virtual void setGetPrintResponse( QByteArray* ba ) = 0;
84+
virtual bool startGetFeatureResponse( QByteArray* ba, const QString& infoFormat ) = 0;
85+
virtual void setGetFeatureResponse( QByteArray* ba ) = 0;
86+
virtual void endGetFeatureResponse( QByteArray* ba ) = 0;
87+
virtual void setGetCoverageResponse( QByteArray* ba ) = 0;
88+
89+
90+
};

python/server/qgsserverfilter.sip

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/***************************************************************************
2+
qgsseerverfilter.h
3+
4+
Server I/O filters class for Qgis Mapserver for use by plugins
5+
-------------------
6+
begin : 2014-09-10
7+
copyright : (C) 2014 by Alessandro Pasotti
8+
email : a dot pasotti at itopen dot it
9+
***************************************************************************/
10+
11+
/***************************************************************************
12+
* *
13+
* This program is free software; you can redistribute it and/or modify *
14+
* it under the terms of the GNU General Public License as published by *
15+
* the Free Software Foundation; either version 2 of the License, or *
16+
* (at your option) any later version. *
17+
* *
18+
***************************************************************************/
19+
20+
/**
21+
* \class QgsServerFilter
22+
* \brief Class defining I/O filters for Qgis Mapserver and
23+
* implemented in plugins.
24+
*
25+
* Filters can define any (or none) of the following hooks:
26+
* * requestReady() - called when request is ready
27+
* * responseComplete() - called when the response is complete
28+
* after core services have returned to main loop
29+
* * sendResponse() - called just before sending output to FGCI
30+
*/
31+
32+
class QgsServerFilter
33+
{
34+
%TypeHeaderCode
35+
#include "qgsserverfilter.h"
36+
#include "qgsserverinterface.h"
37+
%End
38+
39+
public:
40+
41+
/** Constructor
42+
* QgsServerInterface passed to plugins constructors
43+
* and must be passed to QgsServerFilter instances.
44+
*/
45+
QgsServerFilter( QgsServerInterface* serverInterface);
46+
/** Destructor */
47+
virtual ~QgsServerFilter();
48+
/** Return the QgsServerInterface instance*/
49+
QgsServerInterface* serverInterface( );
50+
/** Method called when the QgsRequestHandler is ready and populated with
51+
* parameters, just before entering the main switch for core services.*/
52+
virtual void requestReady();
53+
/** Method called when the QgsRequestHandler processing has done and
54+
* the response is ready, just after the main switch for core services
55+
* and before final sending response to FCGI stdout.
56+
*/
57+
virtual void responseComplete();
58+
/** Method called when the QgsRequestHandler sends its data to FCGI stdout.
59+
* This normally occours at the end of core services processing just after
60+
* the responseComplete() plugin hook. For streaming services (like WFS on
61+
* getFeature requests, sendResponse() might have been called several times
62+
* before the response is complete: in this particular case, sendResponse()
63+
* is called once for each feature before hitting responseComplete()
64+
*/
65+
virtual void sendResponse();
66+
67+
};

python/server/qgsserverinterface.sip

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/***************************************************************************
2+
qgsserverinterface.sip
3+
4+
Class defining the interface made available to server plugins.
5+
-------------------
6+
begin : 2014-09-10
7+
copyright : (C) 2014 by Alessandro Pasotti
8+
email : a dot pasotti at itopen dot it
9+
***************************************************************************/
10+
11+
/***************************************************************************
12+
* *
13+
* This program is free software; you can redistribute it and/or modify *
14+
* it under the terms of the GNU General Public License as published by *
15+
* the Free Software Foundation; either version 2 of the License, or *
16+
* (at your option) any later version. *
17+
* *
18+
***************************************************************************/
19+
20+
/**
21+
* \class QgsServerInterface
22+
* \brief Class defining the interface made available to server plugins.
23+
*
24+
* This class provides methods to access the request handler and
25+
* the capabilties cache. A method to read the environment
26+
* variables set in the main FCGI loop is also available.
27+
* Plugins can add listeners (instances of QgsServerFilter) with
28+
* a certain priority through the registerFilter( QgsServerFilter* , int) method.
29+
*/
30+
31+
32+
typedef QMultiMap<int, QgsServerFilter*> QgsServerFiltersMap;
33+
34+
class QgsServerInterface
35+
{
36+
%TypeHeaderCode
37+
#include "qgsserverinterface.h"
38+
%End
39+
40+
public:
41+
/**Returns the current request handler*/
42+
virtual QgsRequestHandler* requestHandler( ) = 0 /KeepReference/;
43+
/**Returns the capabilities cache*/
44+
virtual QgsCapabilitiesCache* capabiblitiesCache() = 0 /KeepReference/;
45+
// Tansfer ownership to avoid garbage collector to call dtor
46+
/** Register a filter with the given priority. The filter's requestReady()
47+
* and responseReady() methods will be called from the loop*/
48+
virtual void registerFilter( QgsServerFilter* filter /Transfer/, int priority = 0 ) = 0;
49+
/**Return an environment variable set by FCGI*/
50+
virtual QString getEnv(const QString& name ) const = 0;
51+
// Commented because of problems with typedef QgsServerFiltersMap, provided
52+
// methods to alter the filters map into QgsRequestHandler API
53+
// virtual QgsServerFiltersMap filters( ) = 0;
54+
55+
private:
56+
/** Constructor */
57+
QgsServerInterface( );
58+
59+
};
60+

0 commit comments

Comments
 (0)