source: TI03-DataExtractor/branches/old_stuff/dx/cgiInterface.py.bak @ 793

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI03-DataExtractor/branches/old_stuff/dx/cgiInterface.py.bak@793
Revision 793, 18.2 KB checked in by astephen, 13 years ago (diff)

Put all the old code in the old_stuff branch.

  • Property svn:executable set to *
Line 
1"""
2CGIInterface.py
3===============
4
5Output module for the data extractor package delivered via CGI (web).
6
7This module holds the CGIInterface class that is used to write HTML
8output from the data extractor package.
9
10"""
11
12# Import required modules
13
14import os
15import string
16from datasetdb import Datasetdb
17from optionHandler import OptionHandler
18
19# Import package modules and variables
20from common import *
21from config import *
22from errorHandler import *
23from requestDict import *
24
25class CGIInterface:
26    """
27    CGIInterface class - used to generate interactive output based on user requests
28    and available datasets. Typically steps through the following stages:
29    1. datasetGroup page
30    2. dataset page
31    3. variables page
32    4. domain page
33    Current version only creates HTML output.
34    """
35
36    def __init__(self):
37        """
38        __init__ method - prints the http header.
39        """
40        print HTTP_HEADER
41       
42    def writePage(self, request, stage):
43        """
44        Method to write the entire page. This calls a number of methods to display
45        each part of the page.
46        """
47        self.writeHeader()
48        self.writeRequestInfo(request, stage)
49        self.writeForm(request, stage)
50        self.writeFooter()
51 
52    def writeHeader(self, headfile=os.path.join(HTML_DIR, "header.html")):
53        """
54        writeHeader method - writes the header section present on all
55        output pages of the dx.
56        """
57        header=" ".join(open(headfile).readlines())
58        header=header.replace("PACKAGE_NAME", PACKAGE_NAME)
59        header=header.replace("LEFT_LOGO", os.path.join(LOGO_DIR, LEFT_LOGO))
60        header=header.replace("RIGHT_LOGO", os.path.join(LOGO_DIR, RIGHT_LOGO))
61        print header
62
63        # Now write user message if there is one:
64        if MESSAGE_TO_USERS!=None:
65            print """<CENTER><I>
66<FONT FACE="Arial, Helvetica, sans-serif" SIZE="+1" COLOR="RED">*** %s ***</FONT></I></CENTER><BR>""" % MESSAGE_TO_USERS
67
68    def writeFooter(self, footfile=os.path.join(HTML_DIR, "footer.html")):
69        """
70        writeFooter method - writes the footer section present on all
71        output pages of the dx.
72        """
73        lines=open(footfile).read()
74        print lines % ("mailto:"+ADMIN_MAIL_ADDRESS)
75
76    def writeRequestInfo(self, request, stage=0):
77        """
78        Method to write out the current request information.
79        """
80        # Use request wrapper class to access useful methods.
81        self.request=RequestDict(request)
82        self.numDatasets=self.request.getNumDatasets()
83        print '<A HREF="%s">Return to Start</A>' % CGI_NAME
84
85        # Set up link to call each section from a URL link so that you
86        # can switch between one or two datasets
87        selfCaller="%s?" % CGI_NAME
88        first_call=1
89        for key in self.request.keys():
90            if key=="target_page":
91                extra="%s=%s" % (key, "INSERT_STAGE_HERE")
92            else:
93                extra="%s=%s" % (key, self.request[key])
94            if first_call:
95                selfCaller=selfCaller+extra
96                first_call=None
97            else:
98                selfCaller=selfCaller+"&"+extra
99               
100        if self.numDatasets==1:
101            select_link=selfCaller.replace("num_datasets=1", "num_datasets=2")
102            select_link=select_link.replace("target_page=INSERT_STAGE_HERE", "")
103            # Temporary measure - send back to start if changed
104            select_link="%s?num_datasets=2" % CGI_NAME
105            print ' | <A HREF="%s">Select 2 datasets</A>' % select_link
106        elif self.numDatasets==2:
107            select_link=selfCaller.replace("num_datasets=2", "num_datasets=1")
108            select_link=select_link.replace("target_page=INSERT_STAGE_HERE", "")
109            # Temporary measure - send back to start if changed
110            select_link="%s?num_datasets=1" % CGI_NAME
111            print ' | <A HREF="%s">Deselect dataset 2</A>' % select_link
112
113        # Begin an HTML table
114        print '<TABLE WIDTH="100%"><TR class="tablerow"><TD COLSPAN="2">CURRENT REQUEST</TD></TR>'
115
116        print '<TR class="tablerow">'
117
118        for count in range(1, self.numDatasets+1):
119          print '<TD WIDTH="50%%">Dataset %s: ' % count
120          if stage==0:
121            print "None Specified"
122          elif stage>0:
123            display_string=' -&gt; <A HREF="%s">%s</A>' % (selfCaller,
124                           self.request["datasetGroup_%s" % count])
125            print display_string.replace("INSERT_STAGE_HERE", STAGES[0])
126            if stage>1:
127                display_string=' -&gt; <A HREF="%s">%s</A>' % (selfCaller,
128                               self.request["dataset_%s" % count])
129                print display_string.replace("INSERT_STAGE_HERE", STAGES[1])
130                if stage>2:
131                    display_string=' -&gt; <A HREF="%s">%s</A>' % (selfCaller,
132                                   self.request["variable_%s" % count])
133                    print display_string.replace("INSERT_STAGE_HERE", STAGES[2])
134                    if stage>3:
135                        display_string=' -&gt; <A HREF="%s">%s</A>' % (selfCaller,
136                                        "domain selection")
137                        print display_string.replace("INSERT_STAGE_HERE", STAGES[3])
138          print "</TD>"
139        print "</TR></TABLE>"
140        print "</I></B><P>"
141
142
143    def writeForm(self, request, stage=0):
144        """
145        Method to write out the main form options for all except the domain page.
146        """
147        # Use request wrapper class to access useful methods.
148        oh=OptionHandler(self.request["allowed_groups"])
149        this_stage=STAGES[stage+1]
150
151        print '<TABLE WIDTH="100%"><TR class="tablerow"><TD>FURTHER SELECTION</TD></TR></TABLE>'
152        # Begin form in HTML output
153        print """<FORM NAME="extract_info" method="POST" action="%s">
154<INPUT NAME="target_page" TYPE="hidden" VALUE="%s">""" % (CGI_NAME, this_stage)
155        if request.has_key("req_id"):
156            print '<INPUT NAME="req_id" TYPE="hidden" VALUE="%s">' % request["req_id"]
157
158        print '<TABLE WIDTH="100%"><TR>'
159       
160        # Now loop through getting the appropriate list of values to show
161        for dset_num in range(1, self.numDatasets+1):
162            selected_flag=None
163            tableWidth=100/(self.numDatasets)
164            print '<TD WIDTH="%s%%" class="tablestyle" VALIGN="top">' % tableWidth
165            if not self.request.has_key("datasetGroup_%s" % dset_num) or                                                   self.request["target_page"]==STAGES[0] :
166                choices=("Dataset Group %s" % dset_num, oh.getDatasetGroupList())
167           
168            else:
169                if not self.request.has_key("dataset_%s" % dset_num) or                                          self.request["target_page"]==STAGES[1]:
170                    choices=("Dataset %s" % dset_num, oh.getDatasetList(self.request["datasetGroup_%s" %                  dset_num]))
171               
172                else:
173                    if not self.request.has_key("variable_%s" % dset_num) or                                      self.request["target_page"]==STAGES[2]:
174                        if self.request.has_key("datasetURI_%s" % dset_num):
175                            var_list=oh.getVariableList(datasetURI=self.request["datasetURI_%s" % dset_num])
176                        else:
177                            var_list=oh.getVariableList(datasetGroup=self.request["datasetGroup_%s" % dset_num], dataset=self.request["dataset_%s" % dset_num])
178                        choices=("Variable %s" % dset_num, tuple(var_list))
179                   
180                    else:   
181                        if not self.request.has_key("northernExtent") or                                        self.request["target_page"]==STAGES[3]:   
182                            # If domain not defined need to call separate method to display options
183                            # as it is more complicated than a list of radio buttons.
184                            self._writeDomainOptions(oh)
185                            return
186
187            print "<P><B>PLEASE SELECT: %s</B><P>" % choices[0]
188
189            if len(choices[1])==0:
190                # If the user is not allowed to view any datasets then don't advise them
191                # via an error message and point them to the registration pages.
192                errorMessage="""<P>YOU DO NOT HAVE PERMISSION TO ACCESS ANY OF THE DATASETS VISIBLE BY THE DATA EXTRACTOR.
193<P>You can apply for access to datasets at:
194<P><A HREF="%s">%s</A>.<P>
195</B></FONT>
196""" % (REGISTRATION_PAGE, REGISTRATION_PAGE)
197                HandleError(errorMessage, noheader=0, user=self.request["user"])
198            else:
199                # Otherwise, write out the list of options.
200                radio_name=choices[0].lower().replace(" ", "_")
201                if self.request.has_key(radio_name):    selected_flag=self.request[radio_name]
202                if selected_flag==None or selected_flag not in choices[1]:
203                    selected_flag=choices[1][0]
204
205                for choice in choices[1]:
206                    if choice==selected_flag:
207                         print '<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s" CHECKED>%s</INPUT>' %               (radio_name, choice, choice)
208
209                    else:
210                        print '<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s">%s</INPUT>' % (radio_name, choice, choice)           
211            print "</TD>"
212           
213        # More HTML formatting
214        print "</TR></TABLE>"
215        print '<P><INPUT TYPE="submit" NAME="proceed" VALUE="Proceed"><P>'
216        print "</FORM><P>"
217        return
218
219    def _writeDomainOptions(self, optionHandler):
220        """
221        Method to write the domain options. This is called internally from self.writeForm()
222        and is therefore passed the RequestDict instance request.
223        """
224        dsetdb=optionHandler
225
226        # Check if we have a datasetURI for each dataset
227        datasetURIs=[None, None, None]
228        for dset_num in range(1, self.numDatasets+1):
229            if not self.request.has_key("datasetURI_%s" % dset_num):
230                datasetURIs[dset_num]=None
231            else:
232                datasetURIs[dset_num]=self.request["datasetURI_%s" % dset_num]
233        (northernExtent, westernExtent, southernExtent, easternExtent)=dsetdb.getHorizontalSpatialDomain(self.request["datasetGroup_1"],                            self.request["dataset_1"], self.request["variable_1"], datasetURIs[1])
234
235        # timeDict holds time list dictionaries for start and end times,
236        # time units and time interval for each dataset
237        timeDict={}
238        for dset_num in range(1, self.numDatasets+1):
239            start_time={}
240            end_time={}
241            (start_time_list, end_time_list, (interval_value, interval_units))=dsetdb.getTemporalDomain(self.request["datasetGroup_%s" % dset_num], self.request["dataset_%s" % dset_num], self.request["variable_%s" % dset_num], datasetURIs[dset_num])
242     
243            count=0
244            for key in TIME_KEYS:
245                start_time[key]=start_time_list[count]
246                end_time[key]=end_time_list[count]
247                count=count+1
248
249            timeDict["dataset_%s" % dset_num]=(start_time, end_time, interval_value, interval_units)
250        # Now print output
251        print "<P><B>SPATIAL AND TEMPORAL SELECTION</B><P>"
252
253        # Horizontal Domain
254        print '<B>Horizontal Domain</B><P>'
255
256        print """<TABLE><TR><TD WIDTH="33%%"></TD>
257<TD WIDTH="34%%"><INPUT TYPE="text" NAME="northernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Northern Extent </FONT></TD>
258<TD WIDTH="33%%"></TD></TR>
259<TR><TD><INPUT TYPE="text" NAME="westernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Western Extent </FONT></TD>
260<TD></TD>
261<TD><INPUT TYPE="text" NAME="easternExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Eastern Extent </FONT></TD>
262<TD></TD>
263<TR><TD></TD>
264<TD><INPUT TYPE="text" NAME="southernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Southern Extent </FONT></TD>
265<TD></TD></TR></TABLE>
266<input type="button" value="Select from map"
267    onClick="newWindow('%s','window2',550,400);">
268&nbsp;&nbsp; Note that the map Java applet may not work if you do not have Java enabled.<P>
269""" % (northernExtent, westernExtent, easternExtent, southernExtent, MAP_APPLET)
270
271        help_link=os.path.join(EXTRAS_DIR, "help_page.html#interpolation")
272        print """<P>[&nbsp;<A NAME="%s" onClick="help('%s')">Note about interpolation methods.</A>&nbsp;]<P>""" % (help_link, help_link)
273
274        # Vertical domain
275        print '<P><B>Vertical Domain</B><P><TABLE WIDTH="100%"><TR>'
276        for dset_num in range(1, self.numDatasets+1):
277            (levels, vertical_units)=dsetdb.getVerticalSpatialDomain(self.request["datasetGroup_%s" % dset_num], self.request["dataset_%s" % dset_num], self.request["variable_%s" % dset_num], datasetURIs[dset_num])
278
279            if type(levels)==str: levels=(levels,)
280            if len(levels)>3:
281                levboxheight=3
282            else:
283                levboxheight=len(levels)
284
285            print '<TD WIDTH="50%%">Levels<BR><SELECT MULTIPLE NAME="vertical_domain_%s" SIZE="%s" WIDTH="50" VALUE="%s">' % (dset_num, levboxheight, levels[0])
286            lev_selected=" SELECTED"
287            for level in levels:
288                print "<OPTION%s> %s" % (lev_selected, level)
289                lev_selected=""
290            print "</SELECT>"
291            print '<INPUT NAME="vertical_units" TYPE="hidden" VALUE="hPa">'
292            print "</TD>"
293        print "</TR></TABLE>"
294
295        import js_funcs
296        super_index_list=[]
297        for dset_num in range(1, self.numDatasets+1):
298            (start_time, end_time)=timeDict["dataset_%s" % dset_num][:2]
299            # Put together the indices of the start time
300            index_list=[0,0,0,0,0,0] # Assume the start time is beginning of first year
301            # Do month and day
302            if start_time["month"]!=1:   index_list[1]=start_time["month"]-1
303            if start_time["day"]!=1:   index_list[2]=start_time["day"]-1
304            # Do hour, minute, second
305            if start_time["hour"]!=0:   index_list[3]=start_time["hour"]
306            if start_time["min"]!=0:   index_list[4]=start_time["min"]
307            if start_time["sec"]!=0:   index_list[5]=int(start_time["sec"])
308            super_index_list=super_index_list+index_list[:]
309
310            # Put together the indices of the end time
311            index_list=[len(range(start_time["year"], end_time["year"])), 12-1, 31-1, 24-1, 60-1, 60-1] # Assume the end time is end of last year
312            # Do month and day
313            if end_time["month"]!=12:   index_list[1]=end_time["month"]-1
314            if end_time["day"]!=31:   index_list[2]=end_time["day"]-1
315            # Do hour, minute, second
316            if end_time["hour"]!=23:   index_list[3]=end_time["hour"]
317            if end_time["min"]!=59:   index_list[4]=end_time["min"]
318            if end_time["sec"]!=59:   index_list[5]=int(end_time["sec"])
319            super_index_list=super_index_list+index_list[:]
320
321        # Insert javascript functions to do date checking.
322        if len(super_index_list)==12:  super_index_list=super_index_list+[0,0,0,0,0,0,0,0,0,0,0,0]
323        print js_funcs.js_dateCheckFunctionGroup % tuple(super_index_list)     
324
325        # Temporal domain
326        print '<P><B>Time</B><P><TABLE WIDTH="100%"><TR>'
327        for dset_num in range(1, self.numDatasets+1):
328            (interval_value, interval_units)=timeDict["dataset_%s" % dset_num][2:]
329            (start_time, end_time)=timeDict["dataset_%s" % dset_num][:2]
330            print '<INPUT NAME="time_interval_units_%s" TYPE="hidden" VALUE="%s">' % (dset_num, interval_units)
331            print '<INPUT NAME="time_interval_value_%s" TYPE="hidden" VALUE="%s">' % (dset_num, interval_value)
332            print '<TD WIDTH="50%">'
333            print '<TABLE BORDER="1"><TR>'
334
335            for part in ("Dataset %s: Start time" % dset_num, "start", "text", "end", "End time"):
336                if part in ("Dataset %s: Start time" % dset_num, "End time"):
337                    print '<TD COLSPAN="6">%s</TD>' % part
338                else:
339                  field_flag=""
340                  for key in TIME_KEYS:
341                    if part=="text":
342                        print "<TD>%s</TD>" % key
343                    elif part in ("start", "end"):
344                        print """<TD><SELECT NAME="%s_%s_%s" %s onChange="checkDate('%s_%s')">""" % (part, key, dset_num, field_flag, part, dset_num)
345                        if key=="year":
346                            time_format="%.4d"
347                        else:
348                            time_format="%.2d"
349
350                        if interval_units==key:
351                            interval=interval_value
352                        else:
353                            interval=1
354
355                        if key=="month":
356                            fudged_start_time=1
357                            fudged_end_time=12
358                            interval=1
359                        elif key=="day":
360                            if interval_units=="month":
361                                fudged_start_time=start_time[key]
362                                fudged_end_time=end_time[key]
363                            else:
364                                fudged_start_time=1
365                                fudged_end_time=31
366                            interval=1
367                        else:
368                            fudged_end_time=end_time[key]
369                            fudged_start_time=start_time[key]
370
371
372                        for item in range(fudged_start_time, fudged_end_time+1, interval):
373                            print ("<OPTION>"+time_format) % item
374               
375                        print "</SELECT></TD>"
376
377                print "</TR>"
378            print "</TABLE>"
379            print "</TD>"
380
381        print "</TR></TABLE><P>"
382        # Call the javascript to update the date field at start
383        print """<SCRIPT LANGUAGE="Javascript">resetAllDates(%s)</SCRIPT>""" % (dset_num-1)
384        self._writeOutputOptions()
385
386
387    def _writeOutputOptions(self):
388        """
389        Method to write the output format options.
390        """
391        print 'Format <P><SELECT NAME="output_type">'
392        for format in OUTPUT_FORMATS:
393            print "<OPTION>%s</SELECT>" % format
394             
395        print "&nbsp;&nbsp; Note that you should choose NetCDF format if you wish to visualise data."
396 
397        print '<P><INPUT TYPE="submit" NAME="proceed" VALUE="Proceed"><P>'
398        print "</FORM><P>"
399
400
401    def writeResults(self, request):
402        """
403        Method to tell user that there job is underway with details of their selection.
404        Should really make a page to confirm these choices and double confirm if it will
405        take a long time.
406        """
407        print "<H1>Your job is being processed. Please wait...</H1>"
408        print "<P>Your job specification is:<P>"
409        print "<TABLE><TR><TD><B>Field</B></TD><TD><B>Value</B></TD></TR>"
410       
411        for key in request.keys():
412            print "<TR><TD>%s</TD><TD>%s</TD></TR>" % (key, request[key])
413
414        print "</TABLE>"
415        return request
416       
417           
418
419
420       
421
Note: See TracBrowser for help on using the repository browser.