source: TI03-DataExtractor/branches/old_stuff/dx-webservice/wsInterface.py @ 793

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

Put all the old code in the old_stuff branch.

Line 
1"""
2wsInterface.py
3===============
4
5Output module for the data extractor package delivered via a web service.
6
7This module holds the WSInterface 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 *
24from times import *
25
26class WSInterface:
27    """
28    WSInterface class - used to generate interactive output based on user requests
29    and available datasets. Typically steps through the following stages:
30    1. datasetGroup page
31    2. dataset page
32    3. variables page
33    4. domain page
34    Output is python modules
35    """
36
37    def __init__(self):
38        """
39        __init__ method - prints the http header.
40        """
41        # Create a list to carry strings for output
42        pass
43       
44    def writePage(self, request, stage):
45        """
46        Method to write the entire page. This calls a number of methods to display
47        each part of the page.
48        """
49        self.writeHeader()
50        self.writeRequestInfo(request, stage)
51        self.writeForm(request, stage)
52        self.writeFooter()
53 
54    def writeHeader(self):
55        """
56        writeHeader method - writes the header section present on all
57        output pages of the dx.
58        """
59        header="The Data Extractor Web Service, let's go..."
60        print header
61
62        # Now write user message if there is one:
63        if MESSAGE_TO_USERS!=None:
64            print MESSAGE_TO_USERS
65
66    def writeFooter(self):
67        """
68        writeFooter method - writes the footer section present on all
69        output pages of the dx.
70        """
71        print "For help contact: ", ADMIN_MAIL_ADDRESS
72
73    def writeRequestInfo(self, request, stage=0):
74        """
75        Method to write out the current request information.
76        """
77        # Use request wrapper class to access useful methods.
78        self.request=RequestDict(request)
79        self.numDatasets=self.request.getNumDatasets()
80
81
82        print "CURRENT REQUEST"
83
84        for count in range(1, self.numDatasets+1):
85          print ("Dataset %s: " % count),
86          if stage==0:
87            print "None Specified"
88          elif stage>0:
89            display_string=" -> %s" % self.request["datasetGroup_%s" % count]
90            print display_string.replace("INSERT_STAGE_HERE", STAGES[0]),
91            if stage>1:
92                display_string=" -> %s" % self.request["dataset_%s" % count]
93                print display_string.replace("INSERT_STAGE_HERE", STAGES[1]),
94                if stage>2:
95                    display_string=" -> %s" % self.request["variable_%s" % count]
96                    print display_string.replace("INSERT_STAGE_HERE", STAGES[2]),
97                    if stage>3:
98                        display_string=" -> %s" % "domain selection"
99                        print display_string.replace("INSERT_STAGE_HERE", STAGES[3])
100
101    def writeForm(self, request, stage=0):
102        """
103        Method to write out the main form options for all except the domain page.
104        """
105        # Use request wrapper class to access useful methods.
106        oh=OptionHandler(self.request["allowed_groups"])
107        this_stage=STAGES[stage+1]
108
109        print "FURTHER SELECTION"
110        # Listing options
111       
112        # Now loop through getting the appropriate list of values to show
113        for dset_num in range(1, self.numDatasets+1):
114            selected_flag=None
115            tableWidth=100/(self.numDatasets)
116
117            if not self.request.has_key("datasetGroup_%s" % dset_num) or                                                   self.request["target_page"]==STAGES[0] :
118                choices=("Dataset Group %s" % dset_num, oh.getDatasetGroupList())
119           
120            else:
121                if not self.request.has_key("dataset_%s" % dset_num) or                                          self.request["target_page"]==STAGES[1]:
122                    choices=("Dataset %s" % dset_num, oh.getDatasetList(self.request["datasetGroup_%s" %                  dset_num]))
123               
124                else:
125                    if not self.request.has_key("variable_%s" % dset_num) or                                      self.request["target_page"]==STAGES[2]:
126                        if self.request.has_key("datasetURI_%s" % dset_num):
127                            var_list=oh.getVariableList(datasetURI=self.request["datasetURI_%s" % dset_num])
128                        else:
129                            var_list=oh.getVariableList(datasetGroup=self.request["datasetGroup_%s" % dset_num], dataset=self.request["dataset_%s" % dset_num])
130                        choices=("Variable %s" % dset_num, tuple(var_list))
131                   
132                    else:   
133                        if not self.request.has_key("northernExtent") or                                        self.request["target_page"]==STAGES[3]:   
134                            # If domain not defined need to call separate method to display options
135                            # as it is more complicated than a list of radio buttons.
136                            self._writeDomainOptions(oh)
137                            return
138
139            print "PLEASE SELECT: %s" % choices[0]
140
141            if len(choices[1])==0:
142                # If the user is not allowed to view any datasets then don't advise them
143                # via an error message and point them to the registration pages.
144                errorMessage="""<P>YOU DO NOT HAVE PERMISSION TO ACCESS ANY OF THE DATASETS VISIBLE BY THE DATA EXTRACTOR.
145You can apply for access to datasets at:
146%s
147""" % (REGISTRATION_PAGE)
148                HandleError(errorMessage, noheader=0, user=self.request["user"])
149            else:
150                # Otherwise, write out the list of options.
151                radio_name=choices[0].lower().replace(" ", "_")
152                if self.request.has_key(radio_name):    selected_flag=self.request[radio_name]
153                if selected_flag==None or selected_flag not in choices[1]:
154                    selected_flag=choices[1][0]
155
156                for choice in choices[1]:
157                    print "%s [%s]" % (choice, radio_name)       
158        return
159
160    def _writeDomainOptions(self, optionHandler):
161        """
162        Method to write the domain options. This is called internally from self.writeForm()
163        and is therefore passed the RequestDict instance request.
164        """
165        dsetdb=optionHandler
166
167        # Check if we have a datasetURI for each dataset
168        datasetURIs=[None, None, None]
169        for dset_num in range(1, self.numDatasets+1):
170            if not self.request.has_key("datasetURI_%s" % dset_num): 
171                datasetURIs[dset_num]=None
172            else:
173                datasetURIs[dset_num]=self.request["datasetURI_%s" % dset_num]
174        (northernExtent, westernExtent, southernExtent, easternExtent)=dsetdb.getHorizontalSpatialDomain(self.request["datasetGroup_1"],                            self.request["dataset_1"], self.request["variable_1"], datasetURIs[1])
175
176        # timeDict holds time list dictionaries for start and end times,
177        # time units and time interval for each dataset
178        timeDict={}
179        for dset_num in range(1, self.numDatasets+1):
180            (start_time, end_time, (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])
181            timeDict["dataset_%s" % dset_num]=(start_time, end_time, interval_value, interval_units) 
182        # Now print output
183        print "<P><B>SPATIAL AND TEMPORAL SELECTION</B><P>"
184
185        # Horizontal Domain
186        print '<B>Horizontal Domain</B><P>'
187
188        print """<TABLE><TR><TD WIDTH="33%%"></TD>
189<TD WIDTH="34%%"><INPUT TYPE="text" NAME="northernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Northern Extent </FONT></TD>
190<TD WIDTH="33%%"></TD></TR>
191<TR><TD><INPUT TYPE="text" NAME="westernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Western Extent </FONT></TD>
192<TD></TD>
193<TD><INPUT TYPE="text" NAME="easternExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Eastern Extent </FONT></TD>
194<TD></TD>
195<TR><TD></TD>
196<TD><INPUT TYPE="text" NAME="southernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Southern Extent </FONT></TD>
197<TD></TD></TR></TABLE>
198<input type="button" value="Select from map"
199    onClick="newWindow('%s','window2',550,400);">
200&nbsp;&nbsp; Note that the map Java applet may not work if you do not have Java enabled.<P>
201""" % (northernExtent, westernExtent, easternExtent, southernExtent, MAP_APPLET)
202
203        help_link=os.path.join(EXTRAS_DIR, "help_page.html#interpolation")
204        print """<P>[&nbsp;<A NAME="%s" onClick="help('%s')">Note about interpolation methods.</A>&nbsp;]<P>""" % (help_link, help_link)
205
206        # Vertical domain
207        print '<P><B>Vertical Domain</B><P><TABLE WIDTH="100%"><TR>'
208        for dset_num in range(1, self.numDatasets+1):
209            (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])
210
211            if type(levels)==str: levels=(levels,)
212            if len(levels)>3:
213                levboxheight=3
214            else:
215                levboxheight=len(levels)
216
217            print '<TD WIDTH="50%%">Levels<BR><SELECT MULTIPLE NAME="vertical_domain_%s" SIZE="%s" WIDTH="50" VALUE="%s">' % (dset_num, levboxheight, levels[0])
218            lev_selected=" SELECTED"
219            for level in levels:
220                print "<OPTION%s> %s" % (lev_selected, level)
221                lev_selected=""
222            print "</SELECT>"
223            print '<INPUT NAME="vertical_units" TYPE="hidden" VALUE="hPa">' 
224            print "</TD>"
225        print "</TR></TABLE>"
226
227        import js_funcs
228        super_index_list=[]
229        timeBins={}
230        for dset_num in range(1, self.numDatasets+1):
231            (start_time, end_time, interval_value, interval_units)=timeDict["dataset_%s" % dset_num]
232            index_list=[]
233            # Get the bin list for all times
234            timeList=createList(start_time, end_time, (interval_value, interval_units), listtype="tuple")
235            timeBins[dset_num]=getTimeBins(timeList)
236            for i in range(len(start_time)):
237                index_list.append(timeBins[dset_num][i].index(start_time[i]))
238            super_index_list=super_index_list+index_list[:]+index_list[:] 
239
240        # Insert javascript functions to do date checking.
241        if len(super_index_list)==12:  super_index_list=super_index_list+[0,0,0,0,0,0,0,0,0,0,0,0]
242        print js_funcs.js_dateCheckFunctionGroup % tuple(super_index_list)     
243
244        # Temporal domain
245        print '<P><B>Time</B><P><TABLE WIDTH="100%"><TR>'
246        for dset_num in range(1, self.numDatasets+1):
247            (interval_value, interval_units)=timeDict["dataset_%s" % dset_num][2:]
248            (start_time, end_time)=timeDict["dataset_%s" % dset_num][:2]
249            print '<INPUT NAME="time_interval_units_%s" TYPE="hidden" VALUE="%s">' % (dset_num, interval_units) 
250            print '<INPUT NAME="time_interval_value_%s" TYPE="hidden" VALUE="%s">' % (dset_num, interval_value)
251            print '<TD WIDTH="50%">'
252            print '<TABLE BORDER="1"><TR>'
253
254            for part in ("Dataset %s: Start time" % dset_num, "start", "text", "end", "End time"):
255                if part in ("Dataset %s: Start time" % dset_num, "End time"):
256                    print '<TD COLSPAN="6">%s</TD>' % part
257                else:
258                  field_flag=""
259                  count=0
260                  for key in TIME_KEYS:
261                    if part=="text":
262                        print "<TD>%s</TD>" % key
263                    elif part in ("start", "end"):
264                        print """<TD><SELECT NAME="%s_%s_%s" %s onChange="checkDate('%s_%s')">""" % (part, key, dset_num, field_flag, part, dset_num)
265                        if key=="year":
266                            time_format="%.4d"
267                        else:
268                            time_format="%.2d"
269
270                        for item in timeBins[dset_num][count]:
271                            print ("<OPTION>"+time_format) % item
272               
273                        print "</SELECT></TD>"
274                        count=count+1
275
276                print "</TR>"
277            print "</TABLE>"
278            print "</TD>"
279
280        print "</TR></TABLE><P>"
281        # Call the javascript to update the date field at start
282        print """<SCRIPT LANGUAGE="Javascript">resetAllDates(%s)</SCRIPT>""" % (dset_num-1)
283        self._writeOutputOptions()
284
285
286    def _writeOutputOptions(self):
287        """
288        Method to write the output format options.
289        """
290        print 'Format <P><SELECT NAME="output_type">'
291        for format in OUTPUT_FORMATS:
292            print "<OPTION>%s</SELECT>" % format
293             
294        print "&nbsp;&nbsp; Note that you should choose NetCDF format if you wish to visualise data."
295 
296        print '<P><INPUT TYPE="submit" NAME="proceed" VALUE="Proceed"><P>'
297        print "</FORM><P>"
298
299
300    def writeResults(self, request):
301        """
302        Method to tell user that there job is underway with details of their selection.
303        Should really make a page to confirm these choices and double confirm if it will
304        take a long time.
305        """
306        print "<H1>Your job is being processed. Please wait...</H1>"
307        print "<P>Your job specification is:<P>"
308        print "<TABLE><TR><TD><B>Field</B></TD><TD><B>Value</B></TD></TR>"
309       
310        for key in request.keys():
311            print "<TR><TD>%s</TD><TD>%s</TD></TR>" % (key, request[key])
312
313        print "</TABLE>"
314        return request
315       
316           
317
318
319       
320
Note: See TracBrowser for help on using the repository browser.