source: TI04-geosplat/trunk/pygss/GSController.py @ 798

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI04-geosplat/trunk/pygss/GSController.py@798
Revision 798, 9.9 KB checked in by astephen, 14 years ago (diff)

Latest working version with install method.
Can accept more than one file but doesn't combine variables yet.

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"""
6GSController.py
7===============
8
9The core class for controlling the package.
10
11"""
12
13# Import required modules
14import sys
15import os 
16import time 
17
18# Bring package into local scope
19#from serverConfig import BASEDIR
20#sys.path.insert(0, os.path.split(BASEDIR)[0])
21from pygss import *
22
23 
24# Add any other locally required directories in which you have modules.
25for path in LOCAL_PYTHONPATH:
26   sys.path.insert(0, path) 
27
28
29class GSController:
30    """
31    Controls the overall process flow of the a session.
32    This class is called through each stage of the interactive process
33    and responds according to the environment and arguments provided.
34    Note that this class is called by the WSInterface
35    class which then reads various instance variables. As a result, very
36    little is returned from the methods below. Instead the data is stored
37    in the instance object.
38    """
39   
40    def __init__(self, args):
41        """
42        Takes in a group of arguments and then calls the appropriate
43        methods to process the user request.
44        """
45        self.username=None 
46        self.password=None
47        self.userRoles=[]
48        self.sessionID=None
49        self.sessionObj=None
50        self.bag=self.sessionObj # alias       
51        self.secureToken=None
52        self.error=None
53   
54        # Parse the arguments
55        try:
56            self._parseArgs(args)
57        except Exception, error:
58            raise Exception, error
59           
60        # If switched on check security       
61        if self.error==None:
62            if RESTRICTED_DATA==1:
63                try:
64                    self._checkSecurity()
65                except Exception, error:
66                    raise Exception, error   
67            else:
68                self.secureToken=None
69                   
70        # Construct the session object
71        if self.error==None:   
72            try:   
73                self._constructSessionObject()   
74            except Exception, error:
75                raise Exception, error
76
77        # Generate the options object
78        if self.error==None:   
79            try:   
80                self._generateOptions()   
81            except Exception, error:
82                raise Exception, error         
83
84
85        # Write request to a file if it has some content
86        if self.error==None:
87          if overlap(["dataset_1", "variable_1", "sessionID", "numberOfDatasets"], 
88                      self.bag.keys()):                       
89            self.bag["accessTime"]=time.time()             
90            self.sessionObjectManager.writeSessionObject(self.bag) 
91   
92            # Validate the selection against known information
93            try:           
94                self._validate()                   
95            except Exception, error:
96                raise Exception, error
97           
98        # Estimate the cost of the extraction
99        creditChecked=None
100        if self.error==None:   
101          if self.bag.has_key("action") and self.bag["action"]=="checkCredit":     
102            # Check user has sufficient credit
103            try:           
104                self._checkCredit()   
105                creditChecked="yes"                 
106            except Exception, error:
107                raise Exception, error
108
109        # Estimate the cost of the extraction
110        if self.error==None:   
111          if self.bag.has_key("action") and self.bag["action"]=="requestCosts":
112           
113            try:
114                (self.estimatedDuration, self.estimatedVolume)=self._createOutput(costOnly=1)
115                sizeLimitInBytes=REQUEST_SIZE_LIMIT*2L**20
116                # If size is over limit then send a tidy error to the user
117                if self.estimatedVolume>sizeLimitInBytes:
118                    sizeInMB=self.estimatedVolume/(2L**20.)
119                    err="""Your request of %.1f MB is over the current %s MB size limit.       
120The Data Extractor cannot yet deal with such large requests.
121Consider mailing <A HREF="mailto:%s">%s</A> for advice or submit multiple smaller requests.""" % (sizeInMB, 
122                               REQUEST_SIZE_LIMIT, ADMIN_MAIL_ADDRESS, ADMIN_MAIL_ADDRESS)     
123                    errorCatcher=ErrorHandler(None, self.username, self.sessionID)
124                    self.error=errorCatcher.displayError(err)
125                    sys.exit() 
126            except Exception, error:
127                raise Exception, error
128
129        # Process the selections to generate some data
130        if self.error==None:   
131            if (self.bag.has_key("getOutput") or (self.bag.has_key("action") and self.bag["action"]=="createOutput")) and creditChecked==None:
132                # Check user has sufficient credit
133                try:       
134                    self._checkCredit()                     
135                except Exception, error:
136                    raise Exception, error
137                           
138                try:       
139                    self._createOutput()           
140                    self.logger=LogManager(self.bag)       
141                    self.bag["status"]="complete"       
142                    self.logger.logCompletedRequest(self.bag["outputFilePath"])         
143                except Exception, error:
144                    raise Exception, error
145   
146        if self.error==None:
147            print "Saving session details:\n", self.bag, "\n\n" 
148            if self.bag.has_key("action") and self.bag["action"]=="clearRequest":
149                del self.bag["action"]
150            elif self.bag.has_key("action") and self.bag["action"]=="createOutput":
151                del self.bag["action"]
152            elif self.bag.has_key("getOutput"):
153                del self.bag["getOutput"]
154            self.sessionObjectManager.writeSessionObject(self.bag)
155        else:
156            self.logger=LogManager(self.bag) 
157            self.logger.logError(self.error)
158         
159           
160    def _parseArgs(self, args):
161        """
162        Parses the argument dictionary that are sent.
163        """                     
164        self.args={}
165        for key, value in args.items():
166            if type(key)==type(u""):
167                newkey=str(key)
168            else:
169                newkey=key
170                   
171            if type(value)==type(u""):
172                newvalue=str(value)
173            else:
174                newvalue=value
175               
176            self.args[newkey]=newvalue
177           
178   
179        for item in ("username", "password", "secureToken"):
180            if self.args.has_key(item):             
181                value=self.args[item]               
182                setattr(self, item, value)
183                del self.args[item]
184               
185        print "ARGS and SecureToken:", self.args, self.secureToken
186                             
187
188    def _checkSecurity(self):
189        """
190        Checks security by getting username and
191        allowed groups from whatever implementation you have put in place.
192        """
193        secChecker=SecurityManager(self.username, self.password, self.secureToken) 
194        # Do something about logout here as well
195     
196        secCheck=secChecker.validateUser() 
197        self.username=secChecker.username
198
199        if type(secCheck)==type(""):
200            raise secCheck
201        elif type(secCheck)==type([]):
202            (self.secureToken, self.userRoles)=secCheck 
203        else: 
204            raise str(secCheck)+str(type(secCheck))#"No response from Security class!"
205           
206
207    def _constructSessionObject(self):
208        """
209        Ensures that all appropriate arguments are being written
210        to the session object in the correct manner. Note that the
211        session object "sessionObj" is just a dictionary but is read
212        in from a shelve object (if it exists already).
213        """     
214        # self.args now holds the input arguments
215        if not self.args.has_key("sessionID"): 
216            self.sessionObjectManager=SessionObject()
217            self.bag=self.sessionObjectManager.dict
218            #self.sessionObj["targetPage"]=STAGES=[0]
219        else: 
220            self.sessionObjectManager=SessionObject(self.args["sessionID"]) 
221            self.bag=self.sessionObjectManager.readSessionObject() 
222            # Clear the session object if requested
223            if self.args.has_key("clearRequest") or self.args.has_key("newRequest"):
224                self.sessionObjectManager.clearSessionObject(self.bag) 
225               
226        if type(self.sessionID)==type(u""):
227            self.sessionID=str(self.sessionID) 
228               
229        # Update session object with allowed roles at each stage (this is checked every reload)
230        self.bag["userRoles"]=self.userRoles
231
232        # Say it is under construction at present
233        self.bag["status"]="constructing"
234       
235        # Add the rest of the arguments to the session object
236        for key in self.args.keys(): 
237            self.bag[key]=self.args[key] 
238
239        # Might need username later
240        if self.bag.has_key("username"):
241            self.username=self.bag["username"]
242        else:
243            self.bag["username"]=self.username
244   
245
246    def _generateOptions(self):
247        """
248        Method that examines the current status of the request to create an appropriate
249        list of options for the user. Made up of many if clauses to control a logical
250        response to the current request.
251        """
252        if keyPatternMatch(self.bag, "fileURI")==0:
253            print self.bag
254            self.options={"AWAITING_FILEURIS":"AWAITING_FILEURIS"}
255            return
256           
257        self.options=OptionHandler(self.bag["userRoles"], self.username, self.bag).options         
258        return
259       
260       
261    def _validate(self):
262        """
263        Validates the selections made by the user. Returns 1 if successful
264        and a string if failure.
265        """
266        validater=ValidateSelection(self.bag)
267        validResponse=validater.validate()
268        if validResponse!=1:
269            raise validResponse
270           
271     
272    def _checkCredit(self):
273        """
274        Checks if the user has the available credit to the selection task. Returns 1 if successful
275        and a string if failure.
276        """
277        creditChecker=CreditManager(self.username, self.bag)
278        creditResponse=creditChecker.creditCheck()
279        if creditResponse!=1:
280            raise creditResponse
281           
282           
283    def _createOutput(self, costOnly=None):
284        """
285        Creates either data file.
286        """   
287        if costOnly==1:
288            requestCoster=RequestCost(self.bag) 
289            return requestCoster.getDurationAndVolume()                     
290
291        # Now really get data...
292        outman=OutputManager(self.bag) 
293
294        if outman.textOnly:
295            print "FOUND POINT VALUE OUTPUT - send to client."
296            self.message=outman.textOnly
297            # Fill in some request values needed by logger
298            for key in ["outputFilePath", "fileFormat"]:
299                self.bag[key]="NOT_APPLICABLE"     
300            return
301       
302        print """Should really fork this process at this point so that we can return
303              something if likely to be large job."""
304        try:
305            outman.createOutputs() 
306        except:
307            raise Exception, "Problem generating requested output file."
308
309        self.bag["outputFilePath"]=outman.localPath       
310        self.bag["outputURLPath"]=outman.URLPath
311   
Note: See TracBrowser for help on using the repository browser.