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

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

A number of minor bug-fixes including full time validation in client.

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