source: TI03-DataExtractor/branches/repackaging/server/lib/ndg/dx/server/OptionHandler.py @ 1813

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI03-DataExtractor/branches/repackaging/server/lib/ndg/dx/server/OptionHandler.py@1813
Revision 1813, 13.1 KB checked in by spascoe, 14 years ago (diff)

Changes to configuration. You can now test DXWSInterface by putting
server/dxs/configs/server.conf in your ndg.conf. Change the BASEDIR
definition to point to .../server/dxs and startSession('rod', 'rod1')
should work.

Line 
1#   Copyright (C) 2004 CCLRC & NERC( Natural Environment Research Council ).
2#   This software may be distributed under the terms of the
3#   Q Public License, version 1.0 or later. http://ndg.nerc.ac.uk/public_docs/QPublic_license.txt
4
5"""
6OptionHandler.py
7================
8
9Holds the OptionHandler class that is used to generate available
10option lists to send to the user via whichever presentation layer
11is being used.
12
13"""
14
15# Import required modules
16import os
17import sys
18
19# Import package modules including global variables
20from common import *
21from CDMSDataHandler import *
22from CSMLDataHandler import *
23from ECMWFGRIB1NoSubsetDataHandler import *
24from MIDASDataHandler import *
25from DXErrors import *
26from DatasetFormatDecider import *
27
28# Import options
29from ndg.utils.config import config
30configSection = 'ndg.dx.server'
31RESTRICTED_DATA = config.getboolean(configSection, 'RESTRICTED_DATA')
32TOP_LEVEL = config.get(configSection, 'TOP_LEVEL')
33
34class OptionHandler:
35    """
36    Takes a user session object and provides responses on what data is available.
37    All lists are sorted alphanumerically here before being exported to
38    other parts of the dx package.
39    """
40
41    def __init__(self, sessionObj):
42        """
43        Method to initialise class. Calls __init__ method for parent class
44        and sets userRoles and username instance variable.
45        """
46        self.bag=sessionObj
47        self.userRoles=self.bag["userRoles"]
48        self.username=self.bag["username"]
49        self.DXDML=DXDMLHandler()
50        self.options=[]
51       
52        optsRequested=self._getRequestedOptionCategory()
53        # Now populte the self.options dictionary
54        self._populateOptionsDict(optsRequested)
55        if self.bag.has_key("optionCategoryRequested"):
56            del self.bag["optionCategoryRequested"]
57       
58       
59    def _getRequestedOptionCategory(self):
60        """
61        Returns the requested option category (generated if not given).
62        """
63        # Define a parameter to pick up whether user wants a specific set of options
64        optsRequested="undefined"
65        if self.bag.has_key("optionCategoryRequested"):
66            optsRequested=self.bag["optionCategoryRequested"]
67       
68        # Get the required option category (going to highest level for all datasets)
69        if optsRequested=="undefined" or optsRequested in ("datasetGroup", "dataset", "variable"):     
70                if not keyPatternMatch(self.bag, "datasetGroup_") or optsRequested=="datasetGroup":
71                    if TOP_LEVEL=="dataset" and (not keyPatternMatch(self.bag, "dataset_\d+\.\d+", "regex")):
72                        optsRequested="dataset"  # to ensure all options are at this level
73                    elif TOP_LEVEL=="datasetGroup":
74                        # What if you only have datasetURIs?
75                        if keyPatternMatch(self.bag, "datasetURI_\d+", "regex"):
76                            dsuriDict=getDictSubsetMatching(self.bag, "datasetURI_\d+", "regex")
77                           
78                            dsgBag={}
79                            for key,dsuri in dsuriDict.items():
80                                n=int(key.split("_")[-1])
81                                (dsg, ds)=self.DXDML.getDatasetGroupAndDatasetFromURI(dsuri)
82                                if not dsgBag.has_key(n):
83                                    dsgBag[n]={"dsg":dsg, "ds":[]}
84                                dsgBag[n]["ds"].append(ds)
85
86                            # Now bag is full create session selection entries for dataset groups
87                            # and datasets to fill the gaps
88                            for key,value in dsgBag.items():
89                                self.bag["datasetGroup_%s" % key]=value["dsg"]
90                                dscount=1
91                                for ds in value["ds"]:
92                                    self.bag["dataset_%s.%s" % (key, dscount)]=ds
93                            optsRequested="variable" # Since we've now populated dsg and ds from dsuri
94                             
95                        else:
96                            optsRequested="datasetGroup"  # to ensure all options are at this level
97               
98                elif not keyPatternMatch(self.bag, "dataset_\d+\.\d+", "regex"):
99                    optsRequested="dataset"  # to ensure all options are at this level                 
100               
101                elif not keyPatternMatch(self.bag, "variable_\d+\.\d+\.\d+", "regex"):
102                    optsRequested="variable"  # to ensure all options are at this level
103
104        return optsRequested
105
106
107    def _getDatasetInfo(self, dsetNum):
108        """
109        Takes a dataset number and returns the (datasetGroup, dataset, datasetURI) tuple
110        for that variable (replacing with None where not available).
111        """
112        rtitems=[]
113        for item in ["datasetGroup", "dataset", "datasetURI"]:
114            itemNum="%s_%s" % (item, dsetNum)
115
116            if self.bag.has_key(itemNum): 
117                rtitems.append(self.bag[itemNum])
118            else:
119                rtitems.append(None)
120        return tuple(rtitems)
121
122
123    def _populateOptionsDict(self, optsRequested):
124        """
125        Populates the options dictionary according to what was requested or logically comes next.
126        """
127        choices=[]
128        print "OPTS REQ:", optsRequested
129       
130        if optsRequested=="datasetGroup":
131            count=1
132            dsgList=self.getDatasetGroupList()
133
134            for dsg in dsgList:
135                choices.append(("datasetGroup_%s" % count, dsg))
136                count=count+1
137            self.options=choices
138           
139        elif optsRequested=="dataset": 
140            dsgDict=getDictSubsetMatching(self.bag, r"datasetGroup_\d+", "regex")
141            dsgKeys=dsgDict.keys()
142            dsgKeys.sort()
143
144            for dsgKey in dsgKeys:     
145                dsgCode=int(dsgKey.split("_")[-1])
146                dsg=dsgDict[dsgKey]
147                datasets=self.getDatasetList(dsg)
148
149                count=1
150                for ds in datasets:
151                    choices.append(("dataset_%s.%s" % (dsgCode, count), ds))
152                    count=count+1
153               
154            self.options=choices
155           
156        elif optsRequested=="variable": 
157            dsDict=getDictSubsetMatching(self.bag, r"dataset_\d+", "regex")
158            dsKeys=dsDict.keys()
159            dsKeys.sort()
160
161            for dsKey in dsKeys:       
162                dsgCode, dsCode=[int(i) for i in dsKey.split("_")[-1].split(".")]
163               
164                dsgString="datasetGroup_%s" % dsgCode
165                vars=self.getVariableList(self.bag[dsgString], dsDict[dsKey])
166               
167                count=1
168                for var in vars:
169                    choices.append(("variable_%s.%s.%s" % (dsgCode, dsCode, count), var))
170                    count=count+1
171               
172            self.options=choices                   
173
174        if self.options!=[]: 
175            # If datasetGroup, dataset or variable is the option then return
176            return     
177
178        if optsRequested=="domainAndFormat":
179            self.options=self._getDomainOptions()+self._getFormatOptions()
180
181        elif not keyPatternMatch(self.bag, "axis_"):
182            self.options=self._getDomainOptions()       
183
184        elif not keyPatternMatch(self.bag, "outputFormat_") or optsRequested=="outputFormat":
185            self.options=self._getFormatOptions()
186   
187   
188    def _getDomainOptions(self):
189        """
190        Returns the domain options list.
191        """
192        choices=[]
193        varDict=getDictSubsetMatching(self.bag, r"variable_\d+\.\d+\.\d+", "regex")
194        varKeys=varDict.keys()
195        varKeys.sort()
196           
197        for varKey in varKeys:
198            (dsgCode, dsCode, varCode)=[int(i) for i in varKey.split("_")[-1].split(".")]
199            dsgString="datasetGroup_%s" % dsgCode
200            dsString="dataset_%s.%s" % (dsgCode, dsCode)
201
202            datasetGroup=self.bag[dsgString]
203            dataset=self.bag[dsString]
204            dataHandler=DatasetFormatDecider(datasetGroup, dataset).datasetFormat
205            domain=dataHandler.getDomain(datasetGroup, dataset, varDict[varKey])
206            count=1
207           
208            for axis in domain:
209                choices.append(("axis_%s.%s.%s.%s" % (dsgCode, dsCode, varCode, count), axis))
210                count=count+1
211               
212        return choices
213                           
214
215    def _getFormatOptions(self):
216        """
217        Returns the format options.
218        """
219        choices=[]
220        varDict=getDictSubsetMatching(self.bag, r"variable_\d+\.\d+\.\d+", "regex")
221        varKeys=varDict.keys()
222        varKeys.sort()
223           
224        for varKey in varKeys:
225            (dsgCode, dsCode, varCode)=[int(i) for i in varKey.split("_")[-1].split(".")]
226            dsgString="datasetGroup_%s" % dsgCode
227            dsString="dataset_%s.%s" % (dsgCode, dsCode)
228
229            datasetGroup=self.bag[dsgString]
230            dataset=self.bag[dsString]
231            dataHandler=DatasetFormatDecider(datasetGroup, dataset).datasetFormat
232           
233            if isinstance(dataHandler, CDMSDataHandler):
234                outputFormatList=["NetCDF", "NASA Ames"]
235            elif isinstance(dataHandler, CSMLDataHandler):
236                outputFormatList=["CSML/NetCDF"]
237            elif isinstance(dataHandler, MIDASDataHandler):
238                outputFormatList=["ASCII Text"]
239            elif isinstance(dataHandler, ECMWFGRIB1NoSubsetDataHandler):
240                outputFormatList=["GRIB"]
241               
242            choices.append(("outputFormat_%s.%s.%s" % (dsgCode, dsCode, varCode), outputFormatList))
243               
244        return choices
245 
246   
247    def getDatasetGroupList(self):
248        """
249        Returning a sorted list of all the dataset groups available
250        to the particular user.
251        """
252        allDatasetGroups=self.DXDML.getDatasetGroups()
253        availableDatasetGroups=[]
254       
255        for dsg in allDatasetGroups:
256             (permittedRoles, permittedUsers)=self.DXDML.getProtectID(datasetGroup=dsg)
257             
258             if (permittedRoles==["all"] or overlap(permittedRoles, self.userRoles)) or \
259                 (self.username in permittedUsers or RESTRICTED_DATA==0): 
260                 availableDatasetGroups.append(dsg)             
261                 
262        availableDatasetGroups.sort()
263        rtDatasetGroups=[]
264       
265        # Get other metadata links in form (<detailedMetadataLink>, <discoveryMetadataLink>)
266        for dsg in availableDatasetGroups:
267            rtDatasetGroups.append([dsg, self.DXDML.getAssociatedMetadata(dsg)])
268           
269        return rtDatasetGroups
270       
271       
272    def getDatasetList(self, datasetGroup):
273        """
274        Method to return the available datasets within a given dataset group as
275        a sorted list.
276        """
277        rtDatasets=[]
278
279        if datasetGroup==None: 
280            # Get all possible datasets if datasetGroup is NOT defined
281            # This allows it to work with the TOP_LEVEL defined
282            # as 'dataset' rather than 'datasetGroup' (as required by NDG)
283            allDatasetGroups=self.DXDML.getDatasetGroups()
284
285            for dsg in allDatasetGroups:
286                datasetList=self.DXDML.getDatasets(dsg)
287               
288                for ds in datasetList:
289                    (permittedRoles, permittedUsers)=self.DXDML.getProtectID(datasetGroup=dsg, dataset=ds)
290             
291                    if (permittedRoles==["all"] or overlap(permittedRoles, self.userRoles)) or \
292                       (self.username in permittedUsers or RESTRICTED_DATA==0): 
293                        rtDatasets.append(ds)   
294                #rtDatasets=rtDatasets+datasetList
295        else:
296            # Else just get the datasets for this datasetsGroup
297            datasetList=self.DXDML.getDatasets(datasetGroup)
298            for ds in datasetList:
299                (permittedRoles, permittedUsers)=self.DXDML.getProtectID(datasetGroup=datasetGroup, dataset=ds)
300                   
301                if (permittedRoles==["all"] or overlap(permittedRoles, self.userRoles)) or \
302                   (self.username in permittedUsers or RESTRICTED_DATA==0): 
303                    rtDatasets.append(ds)   
304                       
305        rtDatasets.sort()       
306        if rtDatasets==[]:
307            raise DXOptionHandlingError, "No datasets available for that dataset group. Please select another."
308        return rtDatasets
309       
310       
311    def getVariableList(self, datasetGroup=None, dataset=None, datasetURI=None):
312        """
313        Method to return list of available variables for the given datasetGroup
314        and dataset/datasetURI.
315        """ 
316        dataHandler=DatasetFormatDecider(datasetGroup, dataset, datasetURI).datasetFormat
317           
318        rtVariables=dataHandler.getVariables(datasetGroup, dataset, datasetURI)
319        rtVariables.sort()
320        if rtVariables==[]:
321            raise DXOptionHandlingError, "No variables available for that dataset. Please select another."
322       
323        return rtVariables
324   
325
326
327if __name__=="__main__":
328    x=OptionHandler({"userRoles":[], "username":"jane"})
329    print x.options, "\n"
330   
331    x=OptionHandler({"userRoles":[], "username":"jane", "datasetGroup_1":"Test Data Group 2", 
332                          "datasetGroup_2":"Test Data Group 3"})
333    print x.options, "\n"   
334 
335    x=OptionHandler({"userRoles":[], "username":"jane", "datasetGroup_1":"Test Data Group 2", 
336                          "datasetGroup_2":"Test Data Group 3", "dataset_1.1":"Test Dataset 2",
337                          "dataset_2.1":"Test Dataset 3",
338                          "datasetGroup_3":"CSML test dataset group", "dataset_3.1":"CSML test dataset great test"})
339    print x.options, "\n"   
340
341    x=OptionHandler({"userRoles":[], "username":"jane", "datasetGroup_1":"Test Data Group 2", 
342                          "datasetGroup_2":"Test Data Group 3", "dataset_1.1":"Test Dataset 2",
343                          "dataset_2.1":"Test Dataset 3", "variable_1.1.1":"var2", "variable_2.1.1":"var3"})
344    print x.options, "\n"   
345 
346    x=OptionHandler({"userRoles":[], "username":"jane", "datasetGroup_1":"Test Data Group 2", 
347                          "datasetGroup_2":"Test Data Group 3", "dataset_1.1":"Test Dataset 2",
348                          "dataset_2.1":"Test Dataset 3", "variable_1.1.1":"var2", "variable_2.1.1":"var3",
349                          "optionCategoryRequested":"domainAndFormat"})
350
351    print x.options, "\n"       
352
353    x=OptionHandler({"datasetURI_1":"file:/home/as56/abstractWebService/dxs/testdata/testdata1.xml",
354                         "userRoles":[], "username":"jane", "numberOfDatasets":1})
355    print x.options, "\n\n"
356    x=OptionHandler({"datasetGroup_1":"Test Data Group 1", "dataset_1":"Test Dataset 1", "variable_1.1.1":"pqn",
357                         "userRoles":[], "username":"jane", "numberOfDatasets":1})
358    print x.options, "\n"
359
360    x=OptionHandler({"userRoles":[], "username":"jane", "datasetGroup_1":"CSML test dataset group", "dataset_1.1":"CSML test dataset great test", "variable_1.1.1":"var2",  "datasetGroup_2":"Test Data Group 1", "dataset_2.1":"Test Dataset 1", "variable_2.1.1":"pqn", "optionCategoryRequested":"domainAndFormat", })
361    print x.options, "\n"   
Note: See TracBrowser for help on using the repository browser.