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

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

This a complete fix for ticket:863 (I hope) which includes logic
for handling the pagetabs as a consequence.

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