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

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

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