source: TI03-DataExtractor/branches/old_stuff/latest_dx/dx/pydxc/DisplayManager.py @ 793

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

Put all the old code in the old_stuff branch.

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"""
6DisplayManager.py
7=================
8
9Holds the DisplayManager class for displaying HTML output from
10the Data Extractor client.
11
12"""
13
14# Import standard library modules
15import os, re
16
17# Import package modules
18from clientConfig import *
19from common import *
20import DateTimeManager
21import jsFunctions
22
23
24class DisplayManager:
25    """
26    Class for displaying HTML output from the Data Extractor.
27    """         
28   
29    def __init__(self):
30        """
31        Initialiser for display manager. Just gives a handle for the instance.
32        """
33        pass   
34       
35    def _displayHTTPHeader(self):
36        """
37        Prints the HTTP header.
38        """
39        print HTTP_HEADER
40       
41
42    def _displayHTMLHeader(self):
43        """
44        Prints the configured HTML header.
45        """
46        headfile=os.path.join(HTML_DIR_LOCAL_PATH, "header.html")
47        header=" ".join(open(headfile).readlines())
48        header=header.replace("PACKAGE_NAME", PACKAGE_NAME)
49        header=header.replace("WEB_EXTRAS_URL_PATH", WEB_EXTRAS_URL_PATH)
50        header=header.replace("LEFT_LOGO", os.path.join(LOGO_DIR, LEFT_LOGO))
51        header=header.replace("RIGHT_LOGO", os.path.join(LOGO_DIR, RIGHT_LOGO))
52        print header
53
54        # Now write user message if there is one:
55        if MESSAGE_TO_USERS!=None:
56            print """<CENTER><I>
57<FONT FACE="Arial, Helvetica, sans-serif" SIZE="+1" COLOR="RED">*** %s ***</FONT></I></CENTER><BR>""" % MESSAGE_TO_USERS
58
59
60    def _displayIntroduction(self):
61        """
62        Prints an introduction to the service.
63        """
64        print """<P>Welcome to the <B>%s</B>. This product is powered by Python,
65              CDAT and CSML.
66              """ % PACKAGE_NAME
67                     
68
69    def _displaySummaryLine(self, selectionList):
70        """
71        Prints a summary line of what has been selected so far.
72        """
73        print "<P><B>Selected so far:"
74        for item in selectionList:
75            print " -> %s" % item
76
77
78    def _displayLoginBar(self, username, loginStatus, loginMessage=""):
79        """
80        If security applies then display the login information.
81        """
82        if RESTRICTED_DATA:
83            statusMap={"out":"not logged in", "in":"logged in as %s" % username }
84            print "<P><B>Login status: </B>%s&nbsp;&nbsp;&nbsp;&nbsp;" % statusMap[loginStatus]
85            if len(loginMessage)>0:
86                print '<FONT COLOR="red">&nbsp;&nbsp;&nbsp;&nbsp;[ %s ]</FONT>' % loginMessage
87            if loginStatus=="out":
88                # Display a login form
89                print """<FORM NAME="loginForm" method="POST" action="%s">
90                      Username: <INPUT TYPE="text" SIZE="20" NAME="yousirnaim" VALUE="">
91                      Password: <INPUT TYPE="password" SIZE="10" NAME="parcewerd" VALUE="">
92                      <INPUT TYPE="submit" NAME="login" VALUE="Login"></FORM>""" % CGI_SCRIPT_URL_PATH
93            elif loginStatus=="in":
94                # Display a logout form
95                print """<FORM NAME="loginForm" method="POST" action="%s">
96                      <INPUT TYPE="submit" NAME="logout" VALUE="Logout"></FORM>""" % CGI_SCRIPT_URL_PATH                     
97                         
98       
99    def _displayHTMLFooter(self):
100        """
101        Prints the configured HTML footer.
102        """
103        footfile=os.path.join(HTML_DIR_LOCAL_PATH, "footer.html")
104        lines=open(footfile).read()
105        print lines % ("mailto:"+ADMIN_MAIL_ADDRESS)
106
107
108    def _displayErrorMessage(self, msg, sessionID=None, user=None):
109        """
110        Prints an error message, without a header or footer.
111        """
112        print "<P>An error has occurred with this application. The error message received is:<P>"
113        print "<P><B>%s</B>" % msg
114        print "<P>The administrator has been informed of this error and will look into it."
115        print """<P>You can try pressing the <I>Back</I> button to return to the previous page.
116                 Alternatively you can <A HREF="%s">restart your request</A>.""" % CGI_SCRIPT_URL_PATH
117       
118       
119    def _displayErrorPage(self, msg):
120        """
121        Prints an error page, including headers and footer.
122        """
123        self._displayHTTPHeader()
124        self._displayHTMLHeader()
125        self._displayErrorMessage(msg)
126
127       
128    def _displayMainTableHeader(self, sessionID):
129        """
130        Prints the header part of the main table used in the dx
131        web pages.
132        """
133        print '<TABLE WIDTH="100%"><TR>'
134               
135        print '<TABLE WIDTH="100%"><TR class="tablerow"><TD>FURTHER SELECTION</TD></TR></TABLE>'
136        # Begin form in HTML output
137        print """<FORM NAME="extract_info" method="POST" action="%s">""" % CGI_SCRIPT_URL_PATH
138
139        print '<TABLE WIDTH="100%"><TR>'
140        print '<INPUT NAME="sessionID" TYPE="hidden" VALUE="%s">' % sessionID   
141       
142       
143    def _displayMainTableFooter(self):
144        """
145        Prints the footer part of the main table used in the dx
146        web pages.
147        """
148        print "</TR></TABLE>"
149        print '<P><INPUT TYPE="submit" NAME="proceed" VALUE="Proceed"><P>'
150        print "</FORM><P>"
151
152               
153    def _displayOptionsTable(self, optionCategories, options, optionStrings, sessionID, sessionObj):
154        """
155        Prints the options provided in the format (optionCategory, [option1,
156        option2, .., optionN]). Each dataset has these. It also sends the
157        sessionID as a hidden variable.
158        """     
159        #raise str(options)+"<P>"+str(optionStrings)
160#        print '<TD WIDTH="90%" class="tablestyle" VALIGN="top">'
161
162        # Get the category name to show on the
163        itemMap={"datasetGroup":"Dataset Group", "dataset":"Dataset",
164                 "variable":"Variable"} 
165#       print "<P><B>PLEASE SELECT: %s</B><P>" % itemMap[optionCategories[0].split("_")[0]]
166       
167        if len(options)==0:
168            print """<BR><B>You do not have permission to view any of the available options.</B>
169            <P>You can apply for access to datasets at:
170<P><A HREF="%s">%s</A>.<P>
171</B></FONT>
172""" % (REGISTRATION_PAGE, REGISTRATION_PAGE)
173            return
174           
175        # Now loop through getting the appropriate list of values to show       
176        for dsetNumber in range(1, self.numberOfDatasets+1):
177            selectedFlag=None
178            tableWidth=100/(self.numberOfDatasets)
179            print '<TD WIDTH="%s%%" class="tablestyle" VALIGN="top">' % tableWidth
180
181            #print '<P>%s<P>' % options
182            itemTitle=itemMap[optionCategories[0].split("_")[0]]+(" %s" % dsetNumber)
183            print "<P><B>PLEASE SELECT: %s</B><P>" % itemTitle
184           
185            # Otherwise, write out the list of options.
186            radioName=optionCategories[dsetNumber-1]
187            if sessionObj.has_key(radioName):   
188                selectedFlag=sessionObj[radioName]
189               
190            if itemTitle.find("Dataset Group")>-1:
191                # Need to wade through metadata links to deal with this one...
192                datasetGroups=[]
193                detailedMetadataLinks=[]
194                discoveryMetadataLinks=[]
195               
196                for option in options[dsetNumber-1]:
197                    datasetGroups.append(option[0])
198                    detailedMetadataLinks.append(option[1][0])
199                    discoveryMetadataLinks.append(option[1][1])
200                if selectedFlag==None or selectedFlag not in datasetGroups:
201                    selectedFlag=datasetGroups[0]
202                   
203                for option in datasetGroups:
204                    counter=datasetGroups.index(option)
205                    optionString=optionStrings[dsetNumber-1][counter]
206                   
207                    if option==selectedFlag:
208                        print '<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s" CHECKED>%s</INPUT>' % (radioName, option, optionString)                     
209                    else:
210                        print '<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s">%s</INPUT>' % (radioName, option, optionString)                         
211                    if detailedMetadataLinks[counter].lower()!="none":
212                        print '&nbsp;<A HREF="%s">[ Detailed Metadata ]</A>' % detailedMetadataLinks[counter]
213                    if discoveryMetadataLinks[counter].lower()!="none":
214                        print '&nbsp;<A HREF="%s">[ Discovery Metadata ]</A>' % discoveryMetadataLinks[counter]
215                                           
216            else:
217                if selectedFlag==None or selectedFlag not in options[dsetNumber-1]:
218                    selectedFlag=options[dsetNumber-1][0]
219
220                for option in options[dsetNumber-1]:
221                    optionString=optionStrings[dsetNumber-1][options[dsetNumber-1].index(option)]
222                   
223                    if option==selectedFlag:
224                        print '<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s" CHECKED>%s</INPUT>' % (radioName, option, optionString)
225                    else:
226                        print '<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s">%s</INPUT>' % (radioName, option, optionString)     
227                         
228        print "</TD>"
229           
230
231    def _displayUploadForm(self, sessionID):
232        """
233        Displays a form entry for browsing the local system
234        to upload a file. UPLOAD_TEMP_DIR needs to be configured in
235        the clientConfig.py module.
236        """
237        print '<FORM METHOD="post" ACTION="%s" ENCTYPE="multipart/form-data">' % CGI_SCRIPT_URL_PATH
238        print "<P>Please provide the location of the request file you wish to upload:"
239        print """&nbsp;<INPUT TYPE="file" NAME="uploadedFile" VALUE="" SIZE="40">
240                       <INPUT NAME="action" TYPE="hidden" VALUE="parseUploadedFile">
241                       <INPUT NAME="sessionID" TYPE="hidden" VALUE="%s">
242                       <INPUT TYPE="submit" NAME="submit" VALUE="Upload"></FORM><P>\n<FORM>""" % sessionID
243
244
245    def _displayMetadataForm(self, fileName, fileFormat, varList, globalMetadata):
246        """
247        Displays the metadata in the data file.
248        """
249        #print """<INPUT NAME="variable_1" TYPE="hidden" VALUE="pqn">"""
250        print """<P>Thank you for uploading your file to the NetCDF-NASA Ames convertor.
251               The following information has been extracted from the file:
252               <BR><B>Filename:     %s</B>
253               <BR><B>File format:  %s</B>
254               <P><B><FONT SIZE="+1">Variables:</FONT></B>
255               <BR>Select the variables that you wish convert (Default=ALL):<P>""" % (fileName, fileFormat)
256       
257        # Now print the variable list as a form
258        varCount=1
259        print '<BR><INPUT TYPE="hidden" NAME="selectionsMade" VALUE="complete">'
260        for var in varList:
261            longName, varID=var
262            varString=varID
263            displayVar="%s &nbsp;&nbsp;{%s}" % (longName, varID)
264            if varID in ("None", "", None):
265                varString=longName
266                displayVar=varString
267            print '<BR><INPUT TYPE="checkbox" NAME="variable_%s" VALUE="%s" CHECKED>%s</INPUT>' % (varCount, varString, displayVar)
268            #print "<BR>%s (%s)" % tuple(var) # prints var id and long_name
269            varCount=varCount+1
270       
271        outFileMap={"NetCDF":"NASA Ames", "NASA Ames":"NetCDF"}   
272        # Now print metadata
273        print """<P><BR><B><FONT SIZE="+1">Global Metadata</FONT></B>
274              <BR>The following global metadata will be written to your output %s file(s):<P>""" % outFileMap[fileFormat]
275             
276        print '<TABLE BORDER="0">'
277        maxSize=10
278        for item in globalMetadata:
279            key, value=item
280            if key=="VNAME":
281                continue
282                displayKey="VNAME Variables from NASA Ames (modify below to rename)"
283            elif key=="ANAME":
284                continue
285                if value!=None:
286                    displayKey="ANAME Auxiliary Variables from NASA Ames (modify below to rename)"
287                else:
288                    break
289            else:
290                displayKey=key
291               
292            print '<TR><TD WIDTH="25"><B>%s: </B>' % displayKey
293           
294            #print str(type(value))
295            if type(value)!=type(""):
296                # deal with list type by indexing each part
297                try:
298                    value=value.data
299                except:
300                    pass
301                   
302                partCount=1
303                lengthList=[len(str(i)) for i in value]
304                total=0
305                for i in lengthList: total=total+i
306                #print "<P>TOTAL:", total
307                if total<60: 
308                    # Put all on one line
309                    print "<BR>"
310                    separator=""
311                    sizeString="%s" % (max(lengthList)+5)
312                    inputType="textbox"
313                else:
314                    separator="<BR>"
315                    sizeString="100"
316                    inputType="textbox"
317                   
318                #print dir(value), value.data
319                for part in value:
320                    if key in ("VNAMEAAAAAAAAAAA", "ANAMEAAAAAAAA"): # if variable names
321                        partName="%s-RENAMED_%s" % (key, partCount)
322                    else:
323                        partName="%s_%s" % (key, partCount)
324                    part=str(part)                 
325                    print '%s<INPUT TYPE="%s" NAME="%s" VALUE="%s" SIZE="%s"/>' % (separator, inputType, partName, part, sizeString)
326                    partCount=partCount+1
327                print "</TD></TR>"
328               
329            else:
330                size=len(value)     
331                if size>100:
332                    inputType="textbox"
333                else:
334                    inputType="textbox"
335                print '<INPUT TYPE="%s" NAME="%s" VALUE="%s" SIZE="100"/></TD></TR>' % (inputType, key, value)
336            #print "<BR>%s = %s" % tuple(item) # prints name and value of metadata item
337        print "</TABLE>"
338
339
340
341    def _displayOutputPage(self, outputFilePaths):
342        """
343        Displays full HTML page with a link to the output file.
344        """
345        if len(outputFilePaths)==1:
346            file=outputFilePaths[0]
347            print "<P><B>Your output file is available at:</B>"
348            print """<P><A HREF="%s">%s</A><P>""" % (file, file) 
349        else:
350            print "<P><B>Your output files are available at:</B><P>"
351            for file in outputFilePaths:
352                print """<A HREF="%s">%s</A><BR>""" % (file, file) 
353       
354                     
355    def _displayFinalMessage(self, outputMessage=[]):
356        """
357        Prints an a message for the final page.
358        """
359        outputString=""
360        for i in outputMessage: outputString=outputString+"***LINEBREAK***"+str(i)
361        outputString=outputString.replace("<", "&LT;")
362        outputString=outputString.replace(">", "&GT;")
363        outputString=outputString.replace("***LINEBREAK***", "<P>")
364        outputString=outputString.replace("\n\n", "<P>")
365        outputString=outputString.replace("\n", "<BR>")
366       
367        print """<P>Thank you for using <B>%s</B>. You can now download your output file.
368                 <BR>Any output from the conversion package is printed below:
369                 <P><TABLE BORDER="1"><TR><TD BGCOLOR="#EEEEEE"><KBD>%s</KBD></TD></TR></TABLE><P>
370              """ % (PACKAGE_NAME, outputString)
371
372
373    def _displayFeatureOptions(self):
374        """
375        Prints the available Features in a table.
376        """   
377        pass
378       
379       
380    def _displayHorizontalDomainOptions(self, bounds):
381        """
382        Prints a form entry for specifying the horizontal domain.
383        """
384        (northernExtent, westernExtent, southernExtent, easternExtent)=bounds
385
386        # Horizontal Domain
387        print '<B>Horizontal Domain</B><P>'
388
389        print """<TABLE><TR><TD WIDTH="20%%"></TD><TD WIDTH="20%%"></TD>
390<TD WIDTH="20%%" ALIGN="CENTER"><INPUT TYPE="text" NAME="northernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Northern Extent </FONT></TD>
391<TD WIDTH="20%%"></TD><TD WIDTH="20%%"></TD></TR>
392<TR><TD><INPUT TYPE="text" NAME="westernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Western Extent </FONT></TD>
393<TD COLSPAN="3"><B>NOTE ON LAT/LON SELECTION:</B> If you select a single latitude or longitude that is not on the actual grid the nearest neighbouring point will be used.</TD>
394<TD ALIGN="RIGHT"><INPUT TYPE="text" NAME="easternExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Eastern Extent </FONT></TD>
395<TD></TD>
396<TR><TD></TD><TD></TD>
397<TD ALIGN="CENTER"><INPUT TYPE="text" NAME="southernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Southern Extent </FONT></TD>
398<TD></TD><TD></TD></TR></TABLE>
399<input type="button" value="Select from map"
400    onClick="newWindow('%s','window2',550,400);">
401<BR><B>Note about the Java Map Applet:</B> 
402<BR>1. The map will not work if you do not have Java enabled on your browser.
403<BR>2. This applet is known not to work on certain browsers: Mozilla, Konqueror.
404<BR>3. On some browsers you may have to select your subset twice before it registers.<P>
405""" % (northernExtent, westernExtent, easternExtent, southernExtent, MAP_APPLET_URL_PATH)
406
407        helpLink=os.path.join(WEB_EXTRAS_URL_PATH, "help_page.html#interpolation")
408        print """<P>[&nbsp;<A NAME="%s" onClick="help('%s')">Note about interpolation methods.</A>&nbsp;]<P>""" % (helpLink, helpLink)
409
410       
411    def _displayVerticalSpatialDomainOptions(self, options):
412        """
413        Prints a form entry for specifying the vertical domain.
414        """
415        print '<P><B>Vertical Domain</B><P><TABLE WIDTH="100%"><TR>'
416        for dsetNumber in range(1, self.numberOfDatasets+1):
417            (levels, vertical_units)=options[dsetNumber-1]
418
419            if type(levels)==type(""): levels=(levels,)
420            if len(levels)>3:
421                levboxheight=3
422            else:
423                levboxheight=len(levels)
424
425            print """<TD WIDTH="50%%">Levels<BR><SELECT MULTIPLE NAME="verticalDomain_%s"
426                  SIZE="%s" WIDTH="50" VALUE="%s">""" % (dsetNumber, levboxheight, levels[0])
427            levSelected=" SELECTED"
428            for level in levels:
429                print """<OPTION VALUE="%s"%s>%s</OPTION>""" % (level, levSelected, level)
430                levSelected=""
431            print "</SELECT>"
432            print '<INPUT NAME="verticalUnits" TYPE="hidden" VALUE="hPa">' 
433            print "</TD>"
434        print "</TR></TABLE>"
435
436       
437    def _displayTemporalDomainOptions(self, options):
438        """
439        Prints a form entry for specifying the temporal domain.
440        """ 
441        # timeDict holds time list dictionaries for start and end times,
442        # time units and time interval for each dataset
443        timeDict={}
444        for dsetNumber in range(1, self.numberOfDatasets+1):
445            (start_time, end_time, (intervalValue, intervalUnits))=options[dsetNumber-1]
446            timeDict["dataset_%s" % dsetNumber]=(start_time, end_time, intervalValue, intervalUnits) 
447 
448        super_index_list=[]
449        timeBins={}
450        for dsetNumber in range(1, self.numberOfDatasets+1):
451            (start_time, end_time, intervalValue, intervalUnits)=timeDict["dataset_%s" % dsetNumber]
452            index_list=[]
453            # Get the bin list for all times
454            timeList=DateTimeManager.createList(start_time, end_time, (intervalValue, intervalUnits), listtype="tuple")
455            timeBins[dsetNumber]=DateTimeManager.getTimeBins(timeList)
456            for i in range(len(start_time)):
457                index_list.append(timeBins[dsetNumber][i].index(start_time[i]))
458            super_index_list=super_index_list+index_list[:]+index_list[:] 
459
460        # Insert javascript functions to do date checking.
461        if len(super_index_list)==12:  super_index_list=super_index_list+[0,0,0,0,0,0,0,0,0,0,0,0]
462        print jsFunctions.js_dateCheckFunctionGroup % tuple(super_index_list)     
463
464        # Temporal domain
465        print '<P><B>Time</B><P><TABLE WIDTH="100%"><TR>'
466        for dsetNumber in range(1, self.numberOfDatasets+1):
467            (intervalValue, intervalUnits)=timeDict["dataset_%s" % dsetNumber][2:]
468            (start_time, end_time)=timeDict["dataset_%s" % dsetNumber][:2]
469            print '<INPUT NAME="timeIntervalUnits_%s" TYPE="hidden" VALUE="%s">' % (dsetNumber, intervalUnits) 
470            print '<INPUT NAME="timeIntervalValue_%s" TYPE="hidden" VALUE="%s">' % (dsetNumber, intervalValue)
471            print '<TD WIDTH="50%">'
472            print '<TABLE BORDER="1"><TR>'
473
474            for part in ("Dataset %s: Start time" % dsetNumber, "start", "text", "end", "End time"):
475                if part in ("Dataset %s: Start time" % dsetNumber, "End time"):
476                    print '<TD COLSPAN="6">%s</TD>' % part
477                else:
478                  fieldFlag=""
479                  count=0
480                  for key in TIME_KEYS:
481                    if part=="text":
482                        print "<TD>%s</TD>" % key
483                    elif part in ("start", "end"):
484                        print """<TD><SELECT NAME="%s%s_%s" %s onChange="checkDate('%s_%s')">""" % (part, 
485                                   key, dsetNumber, fieldFlag, part, dsetNumber)
486                        if key=="year":
487                            timeFormat="%.4d"
488                        else:
489                            timeFormat="%.2d"
490
491                        for item in timeBins[dsetNumber][count]:
492                            timeItem=timeFormat % item
493                            print """<OPTION VALUE="%s">%s</OPTION>""" % (timeItem, timeItem)
494               
495                        print "</SELECT></TD>"
496                        count=count+1
497
498                print "</TR>"
499            print "</TABLE>"
500            print "</TD>"
501
502        print "</TR></TABLE><P>"
503        # Call the javascript to update the date field at start
504        print """<SCRIPT LANGUAGE="Javascript">resetAllDates(%s)</SCRIPT>""" % (dsetNumber-1)   
505       
506
507
508
509    def _chopUpSummary(self, summary):
510        """
511        Chops up the summary string returning a dictionary of items and a
512        list of keys for that dictionary ordered in an appropriate manner.
513        """
514        summaryDict={}
515        orderedKeys=[]
516        for line in summary.split("\n"):
517            if line.find(":")>-1:
518                (key, value)=line.strip().split(":\t")
519                summaryDict[key]=value
520                orderedKeys.append(key) 
521        return (summaryDict, orderedKeys)               
522
523
524    def _displayDatasetSummaryLine(self, summary, optionCategory, sessionID):
525        """
526        Takes a string containing a request summary and parses into suitable
527        HTML format. Prints a summary line for the current request - with clickable
528        links.
529        """
530        # Chop up the request information into a dictionary
531        summaryDict=self._chopUpSummary(summary)[0]
532               
533        # Set up the form for the actions bar to allow various useful functions
534        print """<FORM NAME="actions_bar" method="POST" action="%s">""" % CGI_SCRIPT_URL_PATH
535       
536        # Show return to start link
537        print '<A HREF="%s?action=clearRequest">Return to Start</A>' % CGI_SCRIPT_URL_PATH
538
539        # Get current number of Datasets before showing option of selecting number of datasets
540        # This sets the instance variable that is re-used everywhere from now on - clunky, I know!
541        self.numberOfDatasets=int(summaryDict["numberOfDatasets"])     
542       
543        if sessionID in (None, "None"):
544            sidString=""
545        else:
546            sidString="&sessionID=%s" % sessionID
547       
548        # Show option for number of datasets if more than one allowed
549        if MAX_NUM_DATASETS>1:
550            print """ | Number of Datasets <SELECT NAME="ndsets" onchange="redirect(this);">"""
551           
552            for n in range(1, MAX_NUM_DATASETS+1):
553                if n==self.numberOfDatasets:
554                    print '<OPTION SELECTED VALUE="%s?numberOfDatasets=%s%s">%s</OPTION>' % (CGI_SCRIPT_URL_PATH, n, sidString, n)
555                else:
556                    print '<OPTION VALUE="%s?numberOfDatasets=%s%s">%s</OPTION>' % (CGI_SCRIPT_URL_PATH, n, sidString, n)
557                   
558            print "</SELECT>"
559       
560        # Link to view request summary
561        print '&nbsp;| <A HREF="%s?action=viewRequestSummary%s">View Current Request Summary</A>' % (CGI_SCRIPT_URL_PATH, sidString)
562       
563        # Allow save of request (XML format)
564        print ' | <A HREF="%s?action=saveRequest%s">Save Request (xml)</A>' % (CGI_SCRIPT_URL_PATH, sidString)
565       
566        # Allow upload of previous request (XML format)
567        print ' | <A HREF="%s?action=uploadRequest%s">Upload Request (xml)</A>' % (CGI_SCRIPT_URL_PATH, sidString)
568       
569        # Close actions bar form
570        print "</FORM>"
571                           
572        # Set up link to call each section from a URL link so that you
573        # can switch between one or two datasets
574        selfCaller="%s?" % CGI_SCRIPT_URL_PATH
575        firstCall=1
576        for key in summaryDict.keys():
577            if key=="targetPage":
578                extra="%s=%s" % (key, "INSERT_STAGE_HERE")
579            elif key=="numberOfDatasets":
580                pass
581            else:
582                extra="%s=%s" % (key, summaryDict[key])
583            if firstCall:
584                selfCaller=selfCaller+extra
585                firstCall=None
586            else:
587                selfCaller=selfCaller+"&"+extra
588        """     
589        if self.numberOfDatasets==1:
590            selectLink=selfCaller.replace("numberOfDatasets=1", "numberOfDatasets=2")
591            selectLink=selectLink.replace("targetPage=INSERT_STAGE_HERE", "")
592            # Temporary measure - send back to start if changed
593            selectLink="%s?numberOfDatasets=2" % CGI_SCRIPT_URL_PATH
594            print ' | <A HREF="%s">Select 2 datasets</A>' % selectLink
595        elif self.numberOfDatasets==2:
596            selectLink=selfCaller.replace("numberOfDatasets=2", "numberOfDatasets=1")
597            selectLink=selectLink.replace("targetPage=INSERT_STAGE_HERE", "")
598            # Temporary measure - send back to start if changed
599            selectLink="%s?numberOfDatasets=1" % CGI_SCRIPT_URL_PATH
600            print ' | <A HREF="%s">Deselect dataset 2</A>' % selectLink"""
601
602        # Begin an HTML table
603        print '<TABLE WIDTH="100%"><TR class="tablerow"><TD COLSPAN="2">CURRENT REQUEST</TD></TR>'
604
605        print '<TR class="tablerow">'
606
607        # Get option category without number
608        optcat=optionCategory.split("_")[0]
609
610        for count in range(1, self.numberOfDatasets+1):
611          print '<TD WIDTH="50%%">Dataset %s: ' % count
612          if not summaryDict.has_key("datasetGroup_%s" % count):
613            print "None Specified"
614          elif summaryDict.has_key("datasetGroup_%s" % count):
615            displayString=' -&gt; <A HREF="%s&targetPage=%s">%s</A>' % (selfCaller, STAGES[0],
616                           summaryDict["datasetGroup_%s" % count])
617            print displayString.replace("INSERT_STAGE_HERE", STAGES[0])
618            if summaryDict.has_key("dataset_%s" % count) and optcat not in ("datasetGroup", "dataset"):
619                displayString=' -&gt; <A HREF="%s&targetPage=%s">%s</A>' % (selfCaller, STAGES[1],
620                               summaryDict["dataset_%s" % count])
621                print displayString.replace("INSERT_STAGE_HERE", STAGES[1])
622                if summaryDict.has_key("variable_%s" % count) and optcat not in ("datasetGroup", "dataset", "variable"):
623                    displayString=' -&gt; <A HREF="%s&targetPage=%s">%s</A>' % (selfCaller, STAGES[2],
624                                   summaryDict["variable_%s" % count])
625                    print displayString.replace("INSERT_STAGE_HERE", STAGES[2])
626                    if summaryDict.has_key("horizontalDomain_%s" % count):
627                        displayString=' -&gt; <A HREF="%s&targetPage=%s">%s</A>' % (selfCaller, STAGES[3],
628                                        "domain selection")
629                        print displayString.replace("INSERT_STAGE_HERE", STAGES[3])
630          print "</TD>"
631        print "</TR></TABLE>"
632        print "</I></B><P>"
633
634
635    def _sensibleTimeString(self, timeInSeconds):
636        """
637        Returns an appropriate string converting timeInSeconds to the most
638        readable units.
639        """
640        if timeInSeconds<1:
641            return "3 seconds"
642        if timeInSeconds<60:
643            return "%d seconds" % timeInSeconds
644        if timeInSeconds<(60*60):
645            (m, s)=divmod(timeInSeconds, 60)
646            return "%s mins %s secs" % (m, s)
647        else:
648            (m, s)=divmod(timeInSeconds, 60)
649            (h, m)=divmod(m, 60)
650            return "%s hrs %s mins" % (h, m)   
651
652
653    def _pathListFilter(self, pathList):
654        """
655        A sensible filter on path lists to a maximum of twenty.
656        """
657        if len(pathList)<21:
658            return pathList
659        else:
660            return pathList[:10]+["..."]+pathList[-10:]
661           
662
663    def _displayOutputFileList(self, pathList):
664        """
665        Prints links to all the files the user has requested.
666        """
667        print "<H3>Output information:</H3>"
668       
669        nfiles=len(pathList)
670        pathList=self._pathListFilter(pathList)
671        if nfiles<21:
672            displayedString="all the files produced"
673        else:
674            displayedString="the first 10 and the last 10 files, the rest follow the same file-naming system"
675       
676        plural="s have"
677        if nfiles==1: plural=" has" 
678        print "%s file%s been successfully written. The table below shows %s." % (nfiles, plural, displayedString)
679        print "<TABLE>"
680        for file in pathList:
681            if file=="...":
682                print """<TR class="tablerow"><TD COLSPAN="3">...</TD>"""
683            else:
684                print """<TR class="tablerow">
685                         <TD><B>%s</B></TD>
686                         <TD><A HREF="%s">  Download  </A></TD>
687                         <TD><A HREF="%s?fileURIList=%s&fileVariable_1.1=SELECT_AUTOMATICALLY">  Visualise  </A></TD>
688                     </TR>""" % (file, file, VISUALISOR_NAME, file)
689        print "</TABLE>"       
690
691
692       
693    def _displayProcessingSection(self, estimatedDuration, estimatedVolume, sessionID):
694        """
695        Method to tell user that there job is underway with details of their selection.
696        """
697        print """<H3>Processing Information:</H3>
698              <P>Your <B>job ID</B> is: %s
699              <P>The estimated duration of your job is:  %s """ %  (sessionID, self._sensibleTimeString(estimatedDuration))
700        print "<P>The estimated volume of your job is: %.2f MB" % ((estimatedVolume/1000000)+0.01)
701        print "<P>Your extraction job is running...</P>"
702       
703        if estimatedDuration>60: 
704            try:
705                mailAddr=getUserEmail() 
706                print "<P>You will be emailed at %s when the job has finished and the output is ready." % mailAddr       
707            except:
708                pass
709               
710        print "<P>Thank you for using the %s." % PACKAGE_NAME
711        print "<P>If you remain on this page it should eventually produce your output but the server may time out if your request is large.<P>"
712
713
714
715    def _displayFileNameRuleOptions(self):
716        """
717        Prints the options for outputting to a single file or
718        multiple files.
719        """
720        pass
721       
722
723    def _displayRequestSummaryTable(self, summary):
724        """
725        Prints a table summarising the current request.
726        """
727        print "<H3>The following is a summary of your request</H3>"
728        print "<TABLE>"
729        # Chop up the request information into a dictionary
730        (summaryDict, orderedKeys)=self._chopUpSummary(summary)
731               
732        for key in orderedKeys:
733            print '<TR class="tablerow"><TD><B>%s</B></TD><TD>%s</TD></TR>' % (key, summaryDict[key])
734       
735        print "</TABLE>"
736       
737
738    def _displayConfirmationSection(self, summary):
739        """
740        Asks the user to confirm their request.
741        """
742        print '<P><INPUT TYPE="submit" NAME="confirm" VALUE="Confirm"> Click the "Confirm" button to fetch your request.<P>'
743       
744        self._displayRequestSummaryTable(summary) 
745
746        print """<P><INPUT TYPE="submit" NAME="confirm" VALUE="Confirm"> Click the "Confirm" button to fetch your request.
747        <BR>If you wish to modify your request please press the <I>Back</I> button on your browser.<P>"""
748        print "</FORM><P>"
749       
750       
751    def _displayOperationOptions(self):
752        """
753        Prints a form entry for specifying the required operation.
754        """
755        pass
756       
757       
758    def _displayOutputFormatOptions(self, options, sessionID):
759        """
760        Prints the available output format options in a form.
761        """
762        print """<P><INPUT TYPE="checkbox" NAME="multipleFileOutput">
763               &nbsp;Use multiple output files [ this is the default large files as limited by the server ]."""
764               
765        print '<P>Format&nbsp;<SELECT NAME="outputFormat">'
766        for format in options:
767            print "<OPTION>%s</OPTION>" % format
768        print "</SELECT>"
769             
770        print "&nbsp;&nbsp; Note that you should choose NetCDF format if you wish to visualise data."
771        print '<P><A HREF="%s?action=saveRequest&sessionID=%s">Get Request XML only.</A>' % (CGI_SCRIPT_URL_PATH, sessionID) 
772        print '<P><INPUT TYPE="submit" NAME="proceed" VALUE="Proceed"><P>'
773        print "</FORM><P>"     
774
775
776    def _displayProcessesTable(self):
777        """
778        Prints the Processes table of current dx processes running.
779        """     
780        pass
781   
782       
783    def _displayUploadRequestOptions(self, sessionID):
784        """
785        Generates an upload box for the user to load their own request.
786        The current request is then overwritten by the uploaded version.
787        """
788        """
789        How might this work.
790        At any point I can click [ Upload Old Request ] which is an XML file.
791        It opens a dialogue box for browse and it is saved onto the server and
792        is referenced as http://localhost/cgi-bin/dxcgi.py?uploadedRequest=something/or/other.xml
793        Then the dx opens it and parses it in, keeping the sessionID but losing all else!
794        NOTE: Needs a visible REQUEST_XML_DIR_LOCAL_PATH dir.
795        """
796        print '<FORM METHOD="post" ACTION="%s" ENCTYPE="multipart/form-data">' % CGI_SCRIPT_URL_PATH
797        print "<P>Please provide the location of the request file you wish to upload:"
798        print """&nbsp;<INPUT TYPE="file" NAME="uploadedFile" VALUE="" SIZE="40">
799                       <INPUT NAME="action" TYPE="hidden" VALUE="parseUploadedFile">
800                       <INPUT NAME="sessionID" TYPE="hidden" VALUE="%s">
801                       <INPUT TYPE="submit" NAME="submit" VALUE="Upload"></FORM><P>""" % sessionID
802
803       
804    def _displaySaveRequestOptions(self, requestString, sessionID):
805        """
806        Generates an XML version of the request and writes this to a file locally.
807        Then the user is pointed to that file in the same way they would be a data
808        file.
809        NOTE: Needs a visible REQUEST_XML_DIR_LOCAL_PATH dir.
810        """
811        # Write the file to the REQUEST_XML_DIR_LOCAL_PATH
812        xmlFileName=sessionID+".xml"
813        xmlFile=open(os.path.join(REQUEST_XML_DIR_LOCAL_PATH, xmlFileName), "w")
814        xmlFile.write(requestString) # =dataSubsetSpecifier file
815        xmlFile.close()
816       
817        httpFilePath=os.path.join(REQUEST_XML_DIR_URL_PATH, xmlFileName)
818       
819        print "<P>You can download your request file from:"
820        print '<P><A HREF="%s">%s</A><P>' % (httpFilePath, httpFilePath)
821
822
823    def _displayReturnLine(self, sessionID):
824        """
825        Displays a link to return to request.
826        """
827        print '<P><A HREF="%s?sessionID=%s">Return to your current request</A><P>' % (CGI_SCRIPT_URL_PATH, sessionID)
828       
Note: See TracBrowser for help on using the repository browser.