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

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

Unstable but latest version with multi-variable support and split hooks
for CDML and CSML.

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
17#import cdms
18import vcs
19import sys
20
21# Import package modules including global variables
22from common import *
23from serverConfig import *
24from CDMSDataHandler import *
25from CSMLDataHandler 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       
51    def _getRequestedOptionCategory(self):
52        """
53        Returns the requested option category (generated if not given).
54        """
55        # Define a parameter to pick up whether user wants a specific set of options
56        optsRequested=None
57        if self.bag.has_key("optionCategoryRequested"):
58            optsRequested=self.bag["optionCategoryRequested"]
59
60        # Get the required option category (going to highest level for all datasets)
61        if optsRequested==None or optsRequested in ("datasetGroup", "dataset", "variable"):     
62            for n in range(1, self.bag["numberOfDatasets"]+1):
63                if isUndefined(self.bag, "datasetGroup_%s" % n) or optsRequested=="datasetGroup":
64                    if TOP_LEVEL=="dataset" and (isUndefined(self.bag, "dataset_%s" % n)):
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 isUndefined(self.bag, "dataset_%s" % n):
70                    optsRequested="dataset"  # to ensure all options are at this level                 
71               
72                elif isUndefined(self.bag, "variable_%s" % n):
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        for n in range(1, self.bag["numberOfDatasets"]+1):         
99       
100            choices=None
101            if optsRequested=="datasetGroup":
102                    choices=("datasetGroup_%s" % n, self.getDatasetGroupList())   
103            elif optsRequested=="dataset":                   
104                    choices=("dataset_%s" % n, 
105                        self.getDatasetList(self.bag["datasetGroup_%s" % n]))
106            elif optsRequested=="variable":
107                choices=("variable_%s" % n, self.getVariableList(self.bag["datasetGroup_%s" % n],
108                         self.bag["dataset_%s" % n]))
109 
110            if choices: 
111                self.options[str(n)]=choices
112       
113        if self.options!={}: 
114            # If datasetGroup, dataset or variable is the option then return
115            return     
116       
117        dsg_ds_dsuri=self._getDatasetInfo(1)
118        dataFileHandler=apply(DatasetFormatDecider, dsg_ds_dsuri).datasetFormat
119               
120        # Now move on to the horizontal domain (fixed for all)           
121        if not self._isHorizontalDomainDefined() and optsRequested in (None, "horizontalDomain"):
122            choices=("horizontalDomain", dataFileHandler.getHorizontalDomain(self.bag["datasetGroup_%s" % 1],
123                     self.bag["dataset_%s" % 1], self.bag["variable_%s" % 1])) 
124            self.options["1"]=choices
125            return
126                     
127        # Now deal with the other axes (varying with each variable).
128        for n in range(1, self.bag["numberOfDatasets"]+1):
129       
130            dsg_ds_dsuri=self._getDatasetInfo(n)
131            dataFileHandler=apply(DatasetFormatDecider, dsg_ds_dsuri).datasetFormat             
132           
133            choices=None 
134            if isUndefined(self.bag, "verticalDomain_%s" % n) and optsRequested in (None, "verticalDomain"):
135                choices=("verticalDomain_%s" % n, dataFileHandler.getVerticalSpatialDomain(self.bag["datasetGroup_%s" % n],
136                         self.bag["dataset_%s" % n], self.bag["variable_%s" % n]))
137                optsRequested="verticalDomain"  # to ensure all options are at this level
138                         
139            elif not self._isTemporalDomainDefined(n) and optsRequested in (None, "temporalDomain"):
140                choices=("temporalDomain_%s" % n, dataFileHandler.getTemporalDomain(self.bag["datasetGroup_%s" % n],
141                         self.bag["dataset_%s" % n], self.bag["variable_%s" % n]))
142                optsRequested="temporalDomain"  # to ensure all options are at this level
143                               
144            if choices:  self.options[str(n)]=choices
145           
146        if self.options!={}: 
147            # If vertical or temporal domain is the option then return
148            return     
149       
150        if isUndefined(self.bag, "outputFormat") and optsRequested in (None, "outputFormat"):
151            choices=("outputFormat", OUTPUT_FORMATS)
152            self.options["1"]=choices
153        return
154   
155   
156    def getDatasetGroupList(self):
157        """
158        Returning a sorted list of all the dataset groups available
159        to the particular user.
160        """
161        allDatasetGroups=self.DXDML.getDatasetGroups()
162        availableDatasetGroups=[]
163       
164        for dsg in allDatasetGroups:
165             (permittedRoles, permittedUsers)=self.DXDML.getProtectID(datasetGroup=dsg)
166             
167             if (permittedRoles==["all"] or overlap(permittedRoles, self.userRoles)) or \
168                 (self.username in permittedUsers or RESTRICTED_DATA==0): 
169                 availableDatasetGroups.append(dsg)             
170                 
171        availableDatasetGroups.sort()
172        rtDatasetGroups=[]
173       
174        # Get other metadata links in form (<detailedMetadataLink>, <discoveryMetadataLink>)
175        for dsg in availableDatasetGroups:
176            rtDatasetGroups.append([dsg, self.DXDML.getAssociatedMetadata(dsg)])
177           
178        return rtDatasetGroups
179       
180       
181    def getDatasetList(self, datasetGroup):
182        """
183        Method to return the available datasets within a given dataset group as
184        a sorted list.
185        """
186        rtDatasets=[]
187
188        if datasetGroup==None: 
189            # Get all possible datasets if datasetGroup is NOT defined
190            # This allows it to work with the TOP_LEVEL defined
191            # as 'dataset' rather than 'datasetGroup' (as required by NDG)
192            allDatasetGroups=self.DXDML.getDatasetGroups()
193
194            for dsg in allDatasetGroups:
195                datasetList=self.DXDML.getDatasets(dsg)
196               
197                for ds in datasetList:
198                    (permittedRoles, permittedUsers)=self.DXDML.getProtectID(datasetGroup=dsg, dataset=ds)
199             
200                    if (permittedRoles==["all"] or overlap(permittedRoles, self.userRoles)) or \
201                       (self.username in permittedUsers or RESTRICTED_DATA==0): 
202                        rtDatasets.append(ds)   
203                #rtDatasets=rtDatasets+datasetList
204        else:
205            # Else just get the datasets for this datasetsGroup
206            datasetList=self.DXDML.getDatasets(datasetGroup)
207            for ds in datasetList:
208                (permittedRoles, permittedUsers)=self.DXDML.getProtectID(datasetGroup=datasetGroup, dataset=ds)
209                   
210                if (permittedRoles==["all"] or overlap(permittedRoles, self.userRoles)) or \
211                   (self.username in permittedUsers or RESTRICTED_DATA==0): 
212                    rtDatasets.append(ds)   
213                       
214        rtDatasets.sort()       
215        if rtDatasets==[]:
216            raise DXOptionHandlingError, "No datasets available for that dataset group. Please select another."
217        return rtDatasets
218       
219       
220    def getVariableList(self, datasetGroup=None, dataset=None, datasetURI=None):
221        """
222        Method to return list of available variables for the given datasetGroup
223        and dataset/datasetURI.
224        """
225        #dsg_ds_dsuri=self._getDatasetInfo(n)
226        #datasetFormatType=apply(DatasetFormatDecider, dsg_ds_dsuri).datasetFormat
227        dataFileHandler=DatasetFormatDecider(datasetGroup, dataset, datasetURI).datasetFormat
228           
229        rtVariables=dataFileHandler.getVariables(datasetGroup, dataset, datasetURI)
230        rtVariables.sort()
231        if rtVariables==[]:
232            raise DXOptionHandlingError, "No variables available for that dataset. Please select another."
233       
234        return rtVariables
235   
236           
237    def _isTemporalDomainDefined(self, dset_num):
238        """
239        Method to check if all required temporal domain fields have been set.
240        Returns 1 if yes and None if no.
241        """
242        for n in range(1, self.bag["numberOfDatasets"]+1):
243            for item in ["startDateTime_%s" % n, "endDateTime_%s" % n]:
244                if item not in self.bag.keys():
245                    return
246        return 1
247   
248   
249    def _isHorizontalDomainDefined(self):
250        """
251        Method to check if all required horizontal domain fields have been set.
252        Returns 1 if yes and None if no.
253        """
254        for hk in HORIZ_KEYS:
255            if not self.bag.has_key(hk):
256                return
257               
258        return 1
259
260
261if __name__=="__main__":
262    x=OptionHandler({"datasetURI_1":"file:/home/as56/abstractWebService/dxs/testdata/testdata1.xml",
263                         "userRoles":[], "username":"jane", "numberOfDatasets":1})
264    print x.options, "\n\n"
265    x=OptionHandler({"datasetGroup_1":"Test Data Group 1", "dataset_1":"Test Dataset 1", "variable_1":"pqn",
266                         "userRoles":[], "username":"jane", "numberOfDatasets":1})
267    print x.options
Note: See TracBrowser for help on using the repository browser.