source: TI05-delivery/ows_framework/trunk/ows_server/ows_server/lib/csml_util.py @ 3770

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

fixing DescribeCoverage? response

Line 
1# Copyright (C) 2007 STFC & NERC (Science and Technology Facilities Council).
2# This software may be distributed under the terms of the
3# Q Public License, version 1.0 or later.
4# http://ndg.nerc.ac.uk/public_docs/QPublic_license.txt
5"""
6csml access routines.
7
8@author: Stephen Pascoe
9"""
10from pylons import c, g, cache, request, session, response
11import csml
12try:
13    import cdms2 as cdms
14except:
15    import cdms
16import os, string
17import zipfile
18import tempfile
19from ndgUtils import ndgObject,ndgRetrieve,xmlHandler2
20
21def get_csml_doc(fileoruri):
22        """
23        Gets a csml document from file or exist when passed a file name or uri         
24               
25        Note, access control is not implemented on file access, only on exist access.
26       
27        """
28        if string.find(fileoruri,'__NDG-A0__') == -1:
29            #it's a local file not an identifier
30            file=fileoruri
31            csml_dir = request.environ['paste.config']['app_conf']['csml_dir']
32            path = os.path.join(csml_dir, file)
33            if os.path.exists(path+'.csml'):
34                f = path+'.csml'
35            elif os.path.exists(path+'.xml'):
36                f = path +'.xml'
37            else:
38                raise ValueError("Cannot find CSML file %s" % file)
39           
40            d = csml.parser.Dataset()
41            d.parse(f)
42       
43        else:
44            #it's an NDG identifier, get the document from exist.
45            uri=fileoruri
46            uriN=ndgObject.ndgObject(uri)
47            cf=request.environ['ndgConfig']
48            requestor=request.environ['REMOTE_ADDR']
49            if 'ndgSec' in session:
50                securityTokens=session['ndgSec']
51            else: securityTokens=None
52            status,x=ndgRetrieve(
53                    uriN,cf,requestor=requestor,
54                    securityTokens=securityTokens)
55           
56            if not status:
57                #then its an access denied message or similar:
58                return x
59
60            # otherwise, convert to an XML doc and continue
61            x=xmlHandler2.xmlHandler(x,string=1)
62            d=csml.parser.Dataset()
63            d.parseElemTree(x.tree)                   
64       
65        return d
66
67#this version of get_csml_doc can be deleted now if no problems found with new version:
68#def get_csml_doc(file):
69    #"""
70    #A trivial document retrieval function.
71
72    #This could be replaced with a proper csml server object that supports
73    #multiple stores (filesystem, exist) and cache's the results for
74    #performance.
75
76    #"""
77    #csml_dir = request.environ['paste.config']['app_conf']['csml_dir']
78    #path = os.path.join(csml_dir, file)
79    #if os.path.exists(path+'.csml'):
80        #f = path+'.csml'
81    #elif os.path.exists(path+'.xml'):
82        #f = path +'.xml'
83    #else:
84        #raise ValueError("Cannot find CSML file %s" % file)
85   
86    #d = csml.parser.Dataset()
87    #d.parse(f)
88     
89    #return d
90
91       
92def extractToNetCDF(feature, sel, publish=False):
93    """
94       performs the CSML subset and returns a filename of the netcdf extract
95       publish flag is used to indicate that the netcdf file should be made available to the webserver (for asynchronous delivery)
96    """
97
98    if publish:
99        #if publishing to download directory is required, do so and return publishable file name
100        #used e.g. in WCS when "STORE = true"
101        extract_dir=request.environ['paste.config']['app_conf']['publish_dir']
102    else:
103        extract_dir = request.environ['paste.config']['app_conf']['tmp_dir']
104         
105    # Subset the feature
106    (fd, filename) = tempfile.mkstemp('.nc', 'csml_wxs_', extract_dir); os.close(fd)
107    if type(feature) is csml.parser.GridSeriesFeature:
108        feature.subsetToGridSeries(ncname=os.path.basename(filename), outputdir=os.path.dirname(filename) ,**sel)
109    elif type(feature) is csml.parser.TrajectoryFeature:
110        feature.subsetToTrajectory(ncname=os.path.basename(filename), outputdir=os.path.dirname(filename) ,**sel)
111    elif type(feature) is csml.parser.PointSeriesFeature:
112        del sel['longitude'] #delete dummy values
113        del sel['latitude'] #delete dummy values
114        feature.subsetToPointSeries(ncname=os.path.basename(filename), outputdir=os.path.dirname(filename) ,**sel)
115    elif type(feature) is csml.parser.RaggedSectionFeature:
116        del sel['longitude'] #delete dummy values
117        del sel['latitude'] #delete dummy values
118        feature.subsetByTime(ncname=os.path.basename(filename), outputdir=os.path.dirname(filename) ,**sel)
119    return filename
120       
121def extractToVariable(feature, sel):
122    """
123      calls extractToNetCDF to get the netcdf file, then returns a cdms variable from this file
124    """
125    #call extractToNetCDF:
126    filename = extractToNetCDF(feature, sel)
127    d = cdms.open(filename)
128    var = d(feature.name.CONTENT, squeeze=1)
129    # Work around for CSML bug
130    #var = d(feature.name.CONTENT, longitude=sel['longitude'], latitude=sel['latitude'],
131    #        squeeze=1)
132
133    d.close()
134    #os.remove(filename)
135    return var
136       
137class CsmlBundle(csml.API.csmlContainer.Container):
138    """
139    A quick stab at bundling CSML.
140
141    """
142    def __init__(self, context, **kwargs):
143        """
144        @param context: A directory path to store the CSML and NetCDF
145        """
146        self.context = context
147        kwargs['csmlpath'] = os.path.join(context, 'container.xml')
148        super(CsmlBundle, self).__init__(**kwargs)
149
150    def add(self, fpd):
151        """
152        Overrides the file storage descriptor so that the CSML points relative to the
153        bundle context
154
155        @warning: THIS IS A HACK!
156
157        """
158        (feature, path, desc) = fpd
159        if os.path.dirname(path) != self.context:
160            raise ValueError, "Extract not in bundle context"
161        desc.fileName.CONTENT = os.path.basename(path)
162
163        return super(CsmlBundle, self).add(fpd)
164
165    def join(self, *p):
166        return os.path.join(self.context, *p)
167
168    def makeBundle(self, file, bundleName=None):
169        """
170        Writes the bundle to a zipfile.
171
172        @param file: path or file-like object (see zipfile docs)
173
174        """
175        if bundleName is None:
176            bundleName = os.path.splitext(os.path.basename(file))[0]
177       
178        zf = zipfile.ZipFile(file, 'w')
179        self.getContents()
180        for f in self.containerContents:
181            zf.write(f, os.path.join(bundleName, os.path.basename(f)))
182        zf.close()
183
184        return file
Note: See TracBrowser for help on using the repository browser.