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

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

Implement 'Selections' tab - a shopping cart type function to
allow the storing of different DIF selections together. Functionality
implemented to allow users to select/unselect DIFs from the results
screen and also to remove them, and remove everything, from the
Selections tab. Also, if KML is available for the DIF, icons are
provided to allow the user to open the file - currently valid for
the GoogleEarth? option but not the ConTerra?. Lastly, checkboxes
are provided - together with a 'select all' one - to allow selection
of multiple DIFs when viewing the associated KML. NB, this latter
functionality is not yet implemented.

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: c.pageTabs.append(('Results',session['results']))
92        if 'lastViewed' in session: c.pageTabs.append(('Display',session['lastViewed']))
93       
94        # make selections tab available at all times - to simplify associated business logic
95        #if 'selection' in session:
96        c.pageTabs.append(('Selections',h.url_for(controller='selectedItems',action='index')))
97#            c.pageTabs.append(('Visualise',h.url_for(controller='visualise', action='index')))
98#            c.pageTabs.append(('Download','Blah'))
99       
100        return WSGIController.__call__(self, environ, start_response)
101   
102class OwsController(BaseController):
103    def __call__(self, environ, start_response):
104
105        # All OWS parameter names are case insensitive.
106        req = request._current_obj()
107        self.ows_params = {}
108        for k in req.params:
109            self.ows_params[k.lower()] = req.params[k]       
110
111        # If the EXCEPTION_TYPE is 'pylons' let Pylons catch any exceptions.
112        # Otherwise send an OGC exception report for any OWS_E.OwsError
113        if 'pylons' in EXCEPTION_TYPE:
114            self._fixOwsAction(environ)
115            return super(OwsController, self).__call__(environ, start_response)
116        else:
117            try:
118                self._fixOwsAction(environ)
119                return super(OwsController, self).__call__(environ, start_response)
120            except OWS_E.OwsError, e:
121                logger.exception(e)
122
123                r=render_response('exception_report', report=e.report, format='xml')
124                r.headers['content-type'] = 'text/xml'
125                return r
126
127
128    def _fixOwsAction(self, environ):
129        # Override the Routes action from the request query parameter
130        try:
131            action = self.ows_params['request']
132        except KeyError:
133            raise OWS_E.MissingParameterValue('REQUEST parameter not specified', 'REQUEST')
134
135        # Check action is a method in self
136        if not getattr(self, action):
137            raise OWS_E.InvalidParameterValue('request=%s not supported' % action, 'REQUEST')
138
139        # override routes action with request
140        environ['pylons.routes_dict']['action'] = action
141        del self.ows_params['request']
142
143    def _loadCapabilities(self):
144        """
145        creates an ows_common.get_capabilities.ServiceMetadata object
146        by consulting the paste configuration and annotations in the
147        controller definition.
148
149        """
150        # Deduce ows_endpoint from routes
151        ows_endpoint = h.url_for(controller=request.environ['pylons.routes_dict']['controller'])
152       
153        #Deduce base_url from config
154        base_url =request.environ['ndgConfig'].get('DEFAULT','server')
155
156       
157        # Get the server-level configuration data from an XML file
158        config = request.environ['paste.config']
159        sm_tree = ET.parse(config['ows_common_config'])
160        sm = ows_common.xml.service_metadata(sm_tree.getroot())
161       
162        # Extract service-level parameters and constraint
163        parameters = getattr(self, '_ows_parameters', {})
164        constraints = getattr(self, '_ows_constraints', {})
165        versions = getattr(self, '_ows_versions', [])
166       
167        # Extract operation-level parameters and constraints
168        od = {}
169        for attr in dir(self):
170            op = getattr(self, attr)
171            if hasattr(op, '_ows_name'):
172                p = getattr(op, '_ows_parameters', {})
173                c = getattr(op, '_ows_constraints', {})
174                od[op._ows_name] = Operation(get=RequestMethod(href=base_url+ows_endpoint),
175                                             post=None,
176                                             parameters=p,
177                                             constraints=c,
178                                             name=op._ows_name)
179       
180        sm.operationsMetadata = OperationsMetadata(od, constraints, parameters)
181        sm.serviceIdentification.serviceTypeVersions = versions
182        return sm
183
184    def _renderCapabilities(self, template='ows/get_capabilities'):
185        """
186        The standard way of returning a Capabilities document.
187
188        Each subclass should implement self._load_capabilities() and call
189        this method to return a response object.
190
191        """
192        c.service_metadata = self._loadCapabilities()       
193        r = render_response(template, format='xml')
194        r.headers['content-type'] = 'text/xml'
195        return r
196
197
198# Include the '_' function in the public names
199__all__ = [__name for __name in locals().keys() if not __name.startswith('_') \
200           or __name == '_']
Note: See TracBrowser for help on using the repository browser.