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

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

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