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

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

Changed all references to serverConfig to point to ndg.utils.config.

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