source: TI05-delivery/ows_framework/trunk/ows_server/ows_server/lib/base.py @ 2905

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/ows_framework/trunk/ows_server/ows_server/lib/base.py@2905
Revision 2905, 6.9 KB checked in by domlowe, 13 years ago (diff)

improved crs support in wcs

Line 
1import urllib
2from base64 import urlsafe_b64encode
3from pylons import Response, c, g, cache, request, session
4from pylons.controllers import WSGIController
5from pylons.decorators import jsonify, validate
6from pylons.templating import render, render_response
7from pylons.helpers import abort, redirect_to, etag_cache
8from pylons.i18n import N_, _, ungettext
9from paste.request import construct_url
10import ows_server.models as model
11import ows_server.lib.helpers as h
12from ows_server.lib.security_util import setSecuritySession, LoginServiceQuery
13from ows_common import exceptions as OWS_E
14from ows_common.operations_metadata import OperationsMetadata, Operation, RequestMethod
15from ows_common.get_capabilities import ServiceMetadata
16import ows_common.xml
17
18
19try:
20    from xml.etree import ElementTree as ET
21except ImportError:
22    from elementtree import ElementTree as ET
23
24import logging
25logger = logging.getLogger('ows_server.lib.base')
26
27# Configure
28EXCEPTION_TYPE = request.environ['ndgConfig'].get('OWS_SERVER', 'exception_type', 'ogc').lower()
29
30
31
32class BaseController(WSGIController):
33   
34    def __call__(self, environ, start_response):       
35        # Insert any code to be run per request here. The Routes match
36        # is under environ['pylons.routes_dict'] should you want to check
37        # the action or route vars here
38       
39        # construct URL picking up setting of server name from config to
40        # avoid exposing absolute URL hidden behind mod_proxy see #857           
41        baseURL = request.environ['ndgConfig'].get('DEFAULT', 'server')
42        c.requestURL = baseURL + urllib.quote(environ.get('PATH_INFO', ''))
43
44        query = '&'.join(["%s=%s" % item for item in request.params.items()])
45        if query:
46            c.requestURL += '?' + query
47
48        # Base 64 encode to enable passing around in 'r' argument of query
49        # string for use with login/logout
50        c.b64encRequestURL = urlsafe_b64encode(c.requestURL)
51
52        if 'h' in request.params:
53            setSecuritySession()
54           
55            if 'panelView' not in session:
56                session['panelView']='History'
57            session.save()
58           
59            # TODO Make the redirect tidier ...
60            qs = LoginServiceQuery.stripFromURI()
61
62            cc=construct_url(environ,querystring=qs)
63            h.redirect_to(cc)
64       
65        #organise the information needed by pagetabs ...
66        # TODO avoid this for the server controllers ...
67       
68        c.pageTabs=[('Search',g.discoveryURL)]
69        if 'results' in session: c.pageTabs.append(('Results',session['results']))
70        if 'lastViewed' in session: c.pageTabs.append(('Display',session['lastViewed']))
71       
72        if 'selection' in session:
73            c.pageTabs.append(('Selections',h.url_for(controller='selection',action='index')))
74            c.pageTabs.append(('Visualise',h.url_for(controller='visualise', action='index')))
75            c.pageTabs.append(('Download','Blah'))
76
77        return WSGIController.__call__(self, environ, start_response)
78   
79class OwsController(BaseController):
80    def __call__(self, environ, start_response):
81
82        # All OWS parameter names are case insensitive.
83        req = request._current_obj()
84        self.ows_params = {}
85        for k in req.params:
86            self.ows_params[k.lower()] = req.params[k]       
87
88        # If the EXCEPTION_TYPE is 'pylons' let Pylons catch any exceptions.
89        # Otherwise send an OGC exception report for any OWS_E.OwsError
90        if 'pylons' in EXCEPTION_TYPE:
91            self._fixOwsAction(environ)
92            return super(OwsController, self).__call__(environ, start_response)
93        else:
94            try:
95                self._fixOwsAction(environ)
96                return super(OwsController, self).__call__(environ, start_response)
97            except OWS_E.OwsError, e:
98                logger.exception(e)
99
100                r=render_response('exception_report', report=e.report, format='xml')
101                r.headers['content-type'] = 'text/xml'
102                return r
103           
104 
105    def _fixOwsAction(self, environ):
106        # Override the Routes action from the request query parameter
107        try:
108            action = self.ows_params['request']
109        except KeyError:
110            raise OWS_E.MissingParameterValue('REQUEST parameter not specified', 'REQUEST')
111
112        # Check action is a method in self
113        if not getattr(self, action):
114            raise OWS_E.InvalidParameterValue('request=%s not supported' % action, 'REQUEST')
115
116        # override routes action with request
117        environ['pylons.routes_dict']['action'] = action
118        del self.ows_params['request']
119
120    def _loadCapabilities(self):
121        """
122        creates an ows_common.get_capabilities.ServiceMetadata object
123        by consulting the paste configuration and annotations in the
124        controller definition.
125
126        """
127        # Deduce ows_endpoint from routes
128        ows_endpoint = h.url_for(controller=request.environ['pylons.routes_dict']['controller'])
129       
130        #Deduce base_url from config
131        base_url =request.environ['ndgConfig'].get('DEFAULT','server')
132
133       
134        # Get the server-level configuration data from an XML file
135        config = request.environ['paste.config']
136        sm_tree = ET.parse(config['ows_common_config'])
137        sm = ows_common.xml.service_metadata(sm_tree.getroot())
138       
139        # Extract service-level parameters and constraint
140        parameters = getattr(self, '_ows_parameters', {})
141        constraints = getattr(self, '_ows_constraints', {})
142        versions = getattr(self, '_ows_versions', [])
143       
144        # Extract operation-level parameters and constraints
145        od = {}
146        for attr in dir(self):
147            op = getattr(self, attr)
148            if hasattr(op, '_ows_name'):
149                p = getattr(op, '_ows_parameters', {})
150                c = getattr(op, '_ows_constraints', {})
151                od[op._ows_name] = Operation(get=RequestMethod(href=base_url+ows_endpoint),
152                                             post=None,
153                                             parameters=p,
154                                             constraints=c,
155                                             name=op._ows_name)
156       
157        sm.operationsMetadata = OperationsMetadata(od, constraints, parameters)
158        sm.serviceIdentification.serviceTypeVersions = versions
159        return sm
160
161    def _renderCapabilities(self, template='ows/get_capabilities'):
162        """
163        The standard way of returning a Capabilities document.
164
165        Each subclass should implement self._load_capabilities() and call
166        this method to return a response object.
167
168        """
169        c.service_metadata = self._loadCapabilities()       
170        r = render_response(template, format='xml')
171        r.headers['content-type'] = 'text/xml'
172        return r
173
174
175# Include the '_' function in the public names
176__all__ = [__name for __name in locals().keys() if not __name.startswith('_') \
177           or __name == '_']
Note: See TracBrowser for help on using the repository browser.