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

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

Adjust displayed tabs; only display Selections tab when Results tab is visible.

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