diff --git a/bindings/python/mapnik/ogcserver/cgiserver.py b/bindings/python/mapnik/ogcserver/cgiserver.py index 63517cb48..96c3e6354 100644 --- a/bindings/python/mapnik/ogcserver/cgiserver.py +++ b/bindings/python/mapnik/ogcserver/cgiserver.py @@ -89,8 +89,9 @@ class Handler(cgi.DebugHandler): eh = ExceptionHandler130(self.debug) else: eh = ExceptionHandler111(self.debug) - req.set_header('Content-Type', eh.mimetype) - req.write(eh.getcontent()) + response = eh.getresponse(reqparams) + req.set_header('Content-Type', response.content_type) + req.write(response.content) def lowerparams(params): reqparams = {} diff --git a/bindings/python/mapnik/ogcserver/common.py b/bindings/python/mapnik/ogcserver/common.py index 543ed6463..6abee362d 100644 --- a/bindings/python/mapnik/ogcserver/common.py +++ b/bindings/python/mapnik/ogcserver/common.py @@ -21,8 +21,13 @@ from exceptions import OGCException, ServerConfigurationError from mapnik import Map, Color, Envelope, render, rawdata, Image, Projection -from PIL.Image import fromstring +from PIL.Image import fromstring, new +from PIL.ImageDraw import Draw from StringIO import StringIO +from copy import deepcopy +from traceback import print_tb +from sys import exc_info +from lxml import etree as ElementTree import re # from elementtree import ElementTree # ElementTree._namespace_map.update({'http://www.opengis.net/wms': 'wms', @@ -208,7 +213,7 @@ class WMSBaseServiceHandler(BaseServiceHandler): try: layer = maplayers[layername] except KeyError: - raise OGCException('Layer not defined: %s.' % layername, 'LayerNotDefined') + raise OGCException('Layer "%s" not defined.' % layername, 'LayerNotDefined') for stylename in layer.styles: if stylename in mapstyles.keys(): m.append_style(stylename, mapstyles[stylename]) @@ -222,5 +227,46 @@ class WMSBaseServiceHandler(BaseServiceHandler): fh = StringIO() im2.save(fh, PIL_TYPE_MAPPING[params['format']]) fh.seek(0) - response = Response(params['format'], fh.read()) - return response \ No newline at end of file + return Response(params['format'], fh.read()) + +class BaseExceptionHandler: + + def __init__(self, debug): + self.debug = debug + + def getresponse(self, params): + code = '' + message = '' + excinfo = exc_info() + if self.debug: + fh = StringIO() + print_tb(excinfo[2], None, fh) + fh.seek(0) + message = '\n' + fh.read() + '\n' + str(excinfo[0]) + ': ' + ', '.join(excinfo[1].args) + '\n' + fh.close() + elif len(excinfo[1].args) > 0: + message = excinfo[1].args[0] + if isinstance(excinfo[1], OGCException) and len(excinfo[1].args) > 1: + code = excinfo[1].args[1] + exceptions = params.get('exceptions', None) + if not exceptions: + exceptions = self.defaulthandler + return self.handlers[exceptions](self, code, message, params) + + def xmlhandler(self, code, message, params): + ogcexcetree = deepcopy(self.xmltemplate) + e = ogcexcetree.find(self.xpath) + e.text = message + if code: + e.set('code', code) + return Response(self.xmlmimetype, ElementTree.tostring(ogcexcetree)) + + def inimagehandler(self, code, message, params): + im = new('L', (int(params['width']), int(params['height']))) + draw = Draw(im) + for count, line in enumerate(message.strip().split('\n')): + draw.text((12,15*(count+1)), line, fill='#FFFFFF') + fh = StringIO() + im.save(fh, PIL_TYPE_MAPPING[params['format']]) + fh.seek(0) + return Response(params['format'], fh.read()) \ No newline at end of file diff --git a/bindings/python/mapnik/ogcserver/exceptions.py b/bindings/python/mapnik/ogcserver/exceptions.py index 877710af7..215de33fd 100644 --- a/bindings/python/mapnik/ogcserver/exceptions.py +++ b/bindings/python/mapnik/ogcserver/exceptions.py @@ -19,34 +19,8 @@ # # $Id$ -from copy import deepcopy -from lxml import etree as ElementTree -from StringIO import StringIO -from traceback import print_tb -from sys import exc_info - class OGCException(Exception): pass class ServerConfigurationError(Exception): - pass - -class BaseExceptionHandler: - - def __init__(self, debug): - self.debug = debug - - def getcontent(self): - excinfo = exc_info() - ogcexcetree = deepcopy(self.xmltemplate) - e = ogcexcetree.find(self.xpath) - if self.debug: - fh = StringIO() - print_tb(excinfo[2], None, fh) - fh.seek(0) - e.text = '\n' + fh.read() + '\n' + str(excinfo[0]) + ': ' + ', '.join(excinfo[1].args) + '\n' - elif len(excinfo[1].args) > 0: - e.text = excinfo[1].args[0] - if isinstance(excinfo[1], OGCException) and len(excinfo[1].args) > 1: - e.set('code', excinfo[1].args[1]) - return ElementTree.tostring(ogcexcetree) \ No newline at end of file + pass \ No newline at end of file diff --git a/bindings/python/mapnik/ogcserver/wms111.py b/bindings/python/mapnik/ogcserver/wms111.py index 156c35097..f310effd6 100644 --- a/bindings/python/mapnik/ogcserver/wms111.py +++ b/bindings/python/mapnik/ogcserver/wms111.py @@ -20,8 +20,9 @@ # $Id$ from common import ParameterDefinition, Response, Version, ListFactory, \ - ColorFactory, CRSFactory, WMSBaseServiceHandler, CRS -from exceptions import OGCException, ServerConfigurationError, BaseExceptionHandler + ColorFactory, CRSFactory, WMSBaseServiceHandler, CRS, \ + BaseExceptionHandler +from exceptions import OGCException, ServerConfigurationError from lxml import etree as ElementTree class ServiceHandler(WMSBaseServiceHandler): @@ -38,10 +39,10 @@ class ServiceHandler(WMSBaseServiceHandler): 'bbox': ParameterDefinition(True, ListFactory(float)), 'width': ParameterDefinition(True, int), 'height': ParameterDefinition(True, int), - 'format': ParameterDefinition(True, str, allowedvalues=('image/png','image/jpeg','image/gif')), - 'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE','FALSE')), + 'format': ParameterDefinition(True, str, allowedvalues=('image/png', 'image/jpeg', 'image/gif')), + 'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')), 'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')), - 'exceptions': ParameterDefinition(False, str, 'application/vnd.ogc.se_xml', ('application/vnd.ogc.se_xml',)) + 'exceptions': ParameterDefinition(False, str, 'application/vnd.ogc.se_xml', ('application/vnd.ogc.se_xml', 'application/vnd.ogc.se_inimage')) } } @@ -92,6 +93,7 @@ class ServiceHandler(WMSBaseServiceHandler): application/vnd.ogc.se_xml + application/vnd.ogc.se_inimage A Mapnik WMS Server @@ -179,7 +181,7 @@ class ServiceHandler(WMSBaseServiceHandler): class ExceptionHandler(BaseExceptionHandler): - mimetype = "application/vnd.ogc.se_xml" + xmlmimetype = "application/vnd.ogc.se_xml" xmltemplate = ElementTree.fromstring(""" @@ -188,4 +190,9 @@ class ExceptionHandler(BaseExceptionHandler): """) - xpath = 'ServiceException' \ No newline at end of file + xpath = 'ServiceException' + + handlers = {'application/vnd.ogc.se_xml': BaseExceptionHandler.xmlhandler, + 'application/vnd.ogc.se_inimage': BaseExceptionHandler.inimagehandler} + + defaulthandler = 'application/vnd.ogc.se_xml' \ No newline at end of file diff --git a/bindings/python/mapnik/ogcserver/wms130.py b/bindings/python/mapnik/ogcserver/wms130.py index 53e4769f9..eb10395bf 100644 --- a/bindings/python/mapnik/ogcserver/wms130.py +++ b/bindings/python/mapnik/ogcserver/wms130.py @@ -20,8 +20,9 @@ # $Id$ from common import ParameterDefinition, Response, Version, ListFactory, \ - ColorFactory, CRSFactory, CRS, WMSBaseServiceHandler -from exceptions import OGCException, ServerConfigurationError, BaseExceptionHandler + ColorFactory, CRSFactory, CRS, WMSBaseServiceHandler, \ + BaseExceptionHandler +from exceptions import OGCException, ServerConfigurationError from lxml import etree as ElementTree class ServiceHandler(WMSBaseServiceHandler): @@ -39,10 +40,10 @@ class ServiceHandler(WMSBaseServiceHandler): 'bbox': ParameterDefinition(True, ListFactory(float)), 'width': ParameterDefinition(True, int), 'height': ParameterDefinition(True, int), - 'format': ParameterDefinition(True, str, allowedvalues=('image/gif','image/png','image/jpeg')), - 'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE','FALSE')), + 'format': ParameterDefinition(True, str, allowedvalues=('image/gif','image/png', 'image/jpeg')), + 'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')), 'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')), - 'exceptions': ParameterDefinition(False, str, 'XML', ('XML',)), + 'exceptions': ParameterDefinition(False, str, 'XML', ('XML', 'INIMAGE')), } } @@ -98,6 +99,7 @@ class ServiceHandler(WMSBaseServiceHandler): XML + INIMAGE A Mapnik WMS Server @@ -196,7 +198,7 @@ class ServiceHandler(WMSBaseServiceHandler): class ExceptionHandler(BaseExceptionHandler): - mimetype = "text/xml" + xmlmimetype = "text/xml" xmltemplate = ElementTree.fromstring(""" """) - xpath = '{http://www.opengis.net/ogc}ServiceException' \ No newline at end of file + xpath = '{http://www.opengis.net/ogc}ServiceException' + + handlers = {'XML': BaseExceptionHandler.xmlhandler, + 'INIMAGE': BaseExceptionHandler.inimagehandler} + + defaulthandler = 'XML' \ No newline at end of file