source: TI03-DataExtractor/trunk/pydxs/OptionHandler.py @ 1715

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI03-DataExtractor/trunk/pydxs/OptionHandler.py@1715
Revision 1715, 12.9 KB checked in by astephen, 13 years ago (diff)

Merged with titania version.

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