source: TI03-DataExtractor/trunk/pydxc/DisplayManager.py @ 1109

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

Stable-ish version with fully-ish working dxc client.

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<P><A HREF="%s"><FONT SIZE="+1">restart your request</FONT></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, summaryDict, optionCategories, options, optionStrings, sessionID, sessionObj):
154        """
155        Displays 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        # Get the category name to show on the
160        itemMap={"datasetGroup":"Dataset Group", "dataset":"Dataset",
161                 "variable":"Variable"} 
162       
163        if len(options)==0:
164            print """<BR><B>You do not have permission to view any of the available options.</B>
165            <P>You can apply for access to datasets at:
166<P><A HREF="%s">%s</A>.<P>
167</B></FONT>
168""" % (REGISTRATION_PAGE, REGISTRATION_PAGE)
169            return
170           
171        # Now loop through getting the appropriate list of values to show       
172        """
173        for dsetNumber in range(1, self.numberOfDatasets+1):
174            selectedFlag=None
175            tableWidth=100/(self.numberOfDatasets)
176            print '<TD WIDTH="%s%%" class="tablestyle" VALIGN="top">' % tableWidth
177
178            #print '<P>%s<P>' % options
179            itemTitle=itemMap[optionCategories[0].split("_")[0]]+(" %s" % dsetNumber)
180            print "<P><B>PLEASE SELECT: %s</B><P>" % itemTitle
181           
182            # Otherwise, write out the list of options.
183            radioName=optionCategories[dsetNumber-1]
184            if sessionObj.has_key(radioName):   
185                selectedFlag=sessionObj[radioName]
186               
187            if itemTitle.find("Dataset Group")>-1:
188                # Need to wade through metadata links to deal with this one...
189                datasetGroups=[]
190                detailedMetadataLinks=[]
191                discoveryMetadataLinks=[]
192               
193                for option in options[dsetNumber-1]:
194                    datasetGroups.append(option[0])
195                    detailedMetadataLinks.append(option[1][0])
196                    discoveryMetadataLinks.append(option[1][1])
197                if selectedFlag==None or selectedFlag not in datasetGroups:
198                    selectedFlag=datasetGroups[0]
199                   
200                for option in datasetGroups:
201                    counter=datasetGroups.index(option)
202                    optionString=optionStrings[dsetNumber-1][counter]
203                   
204                    if option==selectedFlag:
205                        print '<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s" CHECKED>%s</INPUT>' % (radioName, option, optionString)                     
206                    else:
207                        print '<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s">%s</INPUT>' % (radioName, option, optionString)                         
208                    if detailedMetadataLinks[counter].lower()!="none":
209                        print '&nbsp;<A HREF="%s">[ Detailed Metadata ]</A>' % detailedMetadataLinks[counter]
210                    if discoveryMetadataLinks[counter].lower()!="none":
211                        print '&nbsp;<A HREF="%s">[ Discovery Metadata ]</A>' % discoveryMetadataLinks[counter]
212                                           
213            else:
214                if selectedFlag==None or selectedFlag not in options[dsetNumber-1]:
215                    selectedFlag=options[dsetNumber-1][0]
216
217                for option in options[dsetNumber-1]:
218                    optionString=optionStrings[dsetNumber-1][options[dsetNumber-1].index(option)]
219                   
220                    if option==selectedFlag:
221                        print '<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s" CHECKED>%s</INPUT>' % (radioName, option, optionString)
222                    else:
223                        print '<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s">%s</INPUT>' % (radioName, option, optionString)     
224                         
225        print "</TD>" """
226       
227        itemTitle=itemMap[optionCategories[0].split("_")[0]]
228        print "<P><B>PLEASE SELECT: %s</B><P>" % itemTitle
229       
230        if itemTitle=="Dataset Group":
231                # Need to wade through metadata links to deal with this one...
232                selectionIDs=optionCategories
233                datasetGroupValues=[i[0] for i in options]
234                datasetGroupNames=[i[0] for i in optionStrings]
235                detailedMetadataLinks=[i[1][0] for i in options]
236                discoveryMetadataLinks=[i[1][1] for i in options]
237
238                selectedFlag=None                 
239                for i in range(len(selectionIDs)):
240                    selectionID=selectionIDs[i]
241                    datasetGroupValue=datasetGroupValues[i]
242                    datasetGroupName=datasetGroupNames[i]
243                    detailedMetadataLink=detailedMetadataLinks[i]
244                    discoveryMetadataLink=discoveryMetadataLinks[i]     
245                           
246                    if not selectedFlag:
247                        print '<BR><INPUT TYPE="checkBox" NAME="%s" VALUE="%s" CHECKED>%s</INPUT>' % (selectionID, datasetGroupName, datasetGroupValue)                 
248                        selectedFlag=1
249                    else:
250                        print '<BR><INPUT TYPE="checkBox" NAME="%s" VALUE="%s">%s</INPUT>' % (selectionID, datasetGroupName, datasetGroupValue)                     
251
252                    if detailedMetadataLink.lower()!="undefined":
253                        print '&nbsp;<A HREF="%s">[ Detailed Metadata ]</A>' % detailedMetadataLink
254                    if discoveryMetadataLink.lower()!="undefined":
255                        print '&nbsp;<A HREF="%s">[ Discovery Metadata ]</A>' % discoveryMetadataLink
256
257        elif itemTitle=="Dataset":
258                selectionIDs=optionCategories
259                itemValues=options
260                itemNames=optionStrings
261                selectedFlag=None 
262               
263                lastDatasetGroup="WON'T MATCH"             
264                for i in range(len(selectionIDs)):
265                    selectionID=selectionIDs[i]
266                    itemName=itemNames[i]
267                    itemValue=itemValues[i]
268                   
269                    dsgKey=re.match("dataset_(\d+)\.", selectionID).groups()[0]
270                    datasetGroup=summaryDict["datasetGroups"][dsgKey]
271                    if datasetGroup!=lastDatasetGroup:
272                        print """<BR><B>%s -&gt; Dataset selection:</B>""" % datasetGroup           
273
274                    if not selectedFlag:
275                        print '<BR><INPUT TYPE="checkBox" NAME="%s" VALUE="%s" CHECKED>%s</INPUT>' % (selectionID, itemName, itemValue)                 
276                        selectedFlag=1
277                    else:
278                        print '<BR><INPUT TYPE="checkBox" NAME="%s" VALUE="%s">%s</INPUT>' % (selectionID, itemName, itemValue)                     
279               
280                    lastDatasetGroup=datasetGroup       
281                       
282
283        elif itemTitle=="Variable":
284                selectionIDs=optionCategories
285                itemValues=[i[0] for i in options]
286                itemNames=[i[1] for i in optionStrings]
287                selectedFlag=None 
288               
289                lastDataset="WON'T MATCH"
290                lastDatasetGroup="WON'T MATCH"             
291                for i in range(len(selectionIDs)):
292                    selectionID=selectionIDs[i]
293                    itemName=itemNames[i]
294                    itemValue=itemValues[i]
295
296                    (dsgKey, dsKey)=re.match("variable_(\d+)\.(\d+)\.", selectionID).groups()
297                    datasetGroup=summaryDict["datasetGroups"][dsgKey]
298                    dataset=summaryDict["datasets"]["%s.%s" % (dsgKey, dsKey)]
299                    if dataset!=lastDataset or lastDatasetGroup!=datasetGroup:
300                        print """<BR><B>%s -&gt; %s -&gt; Variable selection:</B>""" % (datasetGroup, dataset)
301
302                    if not selectedFlag:
303                        print '<BR><INPUT TYPE="checkBox" NAME="%s" VALUE="%s" CHECKED>%s</INPUT>' % (selectionID, itemName, itemValue)                 
304                        selectedFlag=1
305                    else:
306                        print '<BR><INPUT TYPE="checkBox" NAME="%s" VALUE="%s">%s</INPUT>' % (selectionID, itemName, itemValue)                     
307                   
308                    lastDataset=dataset
309                    lastDatasetGroup=datasetGroup           
310           
311    def _displayDomainOptions(self, summaryDict, optionCategories, options, optionStrings, sessionID):
312        """
313        Displays the domain options for each variable.
314        """     
315        print "<P><B>PLEASE SELECT: Domain options</B><P>"     
316        print "<TABLE>"
317        print """<TR CLASS="tablestyle">
318                        <TD><B>AXIS NAME</B></TD>
319                        <TD><B>AXIS ID</B></TD>
320                        <TD><B>RECOGNISED AS</B></TD>
321                        <TD><B>UNITS</B></TD>
322                        <TD COLSPAN="3"><B>SELECTION</B></TD>
323                        <TD><B>INFORMATION</B></TD></TR>"""
324       
325        # Predefine what we need for the axis selection in terms of interfaces...
326        knownAxisDict={}
327               
328        # Loop through keys to get the number of variables
329        axisDict={}
330        for i in range(len(optionCategories)):
331            optionName=optionCategories[i]
332            varIndex=".".join(optionName.split(".")[:-1])[5:]
333            axisIndex=int(optionName.split(".")[-1])
334            items=options[i]
335            [knownAxis, id, longName, units, listType, unused]=items[:6]       
336           
337            if not axisDict.has_key(varIndex):
338                axisDict[varIndex]={"axes":[]}
339            if knownAxis in ("time", "latitude", "longitude"):
340                axisDict[varIndex][knownAxis]=axisIndex
341           
342            axisDict[varIndex]["axes"].append([optionName, items])
343             
344        axisDictKeys=axisDict.keys()
345        axisDictKeys.sort()
346        #print axisDictKeys
347       
348        for key in axisDictKeys:
349
350            varID=summaryDict["variables"][key]
351            dsgKey, dsKey=re.match("(\d+)\.(\d+)", key).groups()
352            datasetGroup=summaryDict["datasetGroups"][dsgKey]
353            dataset=summaryDict["datasets"]["%s.%s" % (dsgKey, dsKey)]
354            print """<TR><TD COLSPAN="8">&nbsp;</TD></TR>"""   
355            print """<TR CLASS="tablestyle"><TD COLSPAN="8"><B>%s -&gt; %s -&gt; %s</TD></TR>""" % (datasetGroup, dataset, varID)           
356       
357            d=axisDict[key]
358            axes=d["axes"]
359           
360            found={}
361            # Check time, lat and lon
362            for ax in ("time", "latitude", "longitude"):
363                if d.has_key(ax):
364                    found[ax]=d[ax]
365           
366            for axis in axes:
367                (optionName, items)=axis
368                varIndex=".".join(optionName.split(".")[:-1])[5:]
369                axisIndex=int(optionName.split(".")[-1])
370                #items=options[i]
371                [knownAxis, id, longName, units, listType, unused]=items[:6]
372
373                if (found.has_key("latitude") and found.has_key("longitude")) and \
374                        axisIndex in (found["latitude"], found["longitude"]):
375               
376                    if found.has_key("used lat lon"):  continue
377               
378                    if axisIndex==found["latitude"]:
379                        # The current axis is latitude so need to get longitude
380                        latItems=items         
381                        latOptionName=optionName       
382                        lonIndex=found["longitude"]
383                       
384                        for x in axes:
385                            if int(x[0].split(".")[-1])==lonIndex:
386                                # Found longitude axis in list
387                                (lonOptionName, lonItems)=x                     
388                       
389                    elif axisIndex==found["longitude"]:
390                        # The current axis is longitude so need to get latitude
391                        lonItems=items
392                        lonOptionName=optionName                       
393                        latIndex=found["latitude"]
394                       
395                        for x in axes:
396                            if int(x[0].split(".")[-1])==latIndex:
397                                # Found latitude axis in list
398                                (latOptionName, latItems)=x             
399                                                               
400                    [latKnownAxis, latId, latLongName, latUnits, latListType, latUnused]=latItems[:6]
401                    northernExtent, southernExtent=latItems[6:8]
402                    [lonKnownAxis, lonId, lonLongName, lonUnits, lonListType, lonUnused]=lonItems[:6]
403                    westernExtent, easternExtent=lonItems[6:8]
404   
405                    found["used lat lon"]=1
406                     
407                    #print '<B>Horizontal Domain</B><P>'
408                     
409                    print """<TR><TD WIDTH="20%%"><B>%s</B></TD>
410                     <TD WIDTH="30%%">%s</TD>
411                     <TD>%s</TD>
412                     <TD>%s</TD>
413                     <TD></TD>                               
414                     <TD><INPUT TYPE="text" NAME="%s" VALUE="%s"/></TD>
415                     <TD><B></B></TD>
416                     </TR>""" % (latLongName, latOptionName, latKnownAxis, latUnits, 
417                                   latOptionName+"_high", northernExtent) 
418                                                                             
419                    print """<TR><TD WIDTH="20%%"><B>%s</B></TD>
420                     <TD WIDTH="30%%">%s</TD>
421                     <TD>%s</TD>
422                     <TD>%s</TD>                     
423                     <TD><INPUT TYPE="text" NAME="%s" VALUE="%s"/></TD>
424                     <TD><TABLE BORDER="0"><TR><TD ALIGN="LEFT">&nbsp;<B></B></TD><TD ALIGN="RIGHT"><B></B>&nbsp;</TD></TR></TABLE></TD>                     
425                     <TD><INPUT TYPE="text" NAME="%s" VALUE="%s"/></TD>
426                     </TR>""" % (lonLongName, lonOptionName, lonKnownAxis, lonUnits, 
427                                   lonOptionName+"_low", westernExtent, lonOptionName+"_high",
428                                   easternExtent) 
429                                                   
430                    print """<TR><TD WIDTH="20%%"><B>%s</B></TD>
431                     <TD WIDTH="30%%">%s</TD>
432                     <TD>%s</TD>
433                     <TD>%s</TD>                     
434                     <TD></TD>                               
435                     <TD><INPUT TYPE="text" NAME="%s" VALUE="%s"/></TD>
436                     <TD><B>&nbsp;</B></TD>
437                     </TR>""" % ("","","","", 
438                                   latOptionName+"_low", southernExtent)                   
439
440                elif found.has_key("time") and axisIndex==found["time"]:
441                    (start,end,intervalValue)=items[6:9]
442                    print """<TR><TD WIDTH="20%%"><B>%s</B></TD>
443                     <TD WIDTH="30%%">%s</TD>
444                     <TD>%s</TD>
445                     <TD>%s</TD>""" % (longName, optionName, knownAxis, units)
446
447                    self._displayTemporalDomainMenus(start, end, intervalValue, units, optionName)
448                             
449                    """<TD><INPUT TYPE="text" NAME="%s" VALUE="%s"/></TD>
450                     <TD><TABLE BORDER="0"><TR><TD ALIGN="LEFT">&nbsp;<B>Low</B></TD><TD ALIGN="RIGHT"><B>High</B>&nbsp;</TD></TR></TABLE></TD>                     
451                     <TD><INPUT TYPE="text" NAME="%s" VALUE="%s"/></TD>
452                     </TR>""" % (optionName+"_low", start, optionName+"_high", end)   
453                         
454                else:
455                    start,end=items[6:8]
456                    print """<TR><TD WIDTH="20%%"><B>%s</B></TD>
457                     <TD WIDTH="30%%">%s</TD>
458                     <TD>%s</TD>
459                     <TD>%s</TD>                     
460                     <TD><INPUT TYPE="text" NAME="%s" VALUE="%s"/></TD>
461                     <TD><TABLE BORDER="0"><TR><TD ALIGN="LEFT">&lt;&nbsp;<B>Low</B></TD><TD ALIGN="RIGHT"><B>High</B>&nbsp;&gt;</TD></TR></TABLE></TD>             
462                     <TD><INPUT TYPE="text" NAME="%s" VALUE="%s"/></TD>
463                     </TR>""" % (longName, optionName, knownAxis, units, 
464                     optionName+"_low", start, optionName+"_high", end)   
465
466            # Fudge output format for now
467            print """<TR><TD WIDTH="20%%"><B>OUTPUT FORMAT</B></TD>"""
468            print """<TD COLSPAN="4">Note that you should choose NetCDF format if you wish to visualise data.</TD>"""               
469            print '<TD COLSPAN="3"><SELECT NAME="outputFormat_%s">' % key
470            for format in ("NetCDF", "NASA Ames"):
471                print "<OPTION>%s</OPTION>" % format
472            print "</SELECT></TD>"
473                     
474        print "</TABLE>"
475
476        print """<P><INPUT TYPE="checkbox" NAME="multipleFileOutput">
477               &nbsp;Use multiple output files [ this is the default large files as limited by the server ]."""
478               
479
480    def _displayUploadForm(self, sessionID):
481        """
482        Displays a form entry for browsing the local system
483        to upload a file. UPLOAD_TEMP_DIR needs to be configured in
484        the clientConfig.py module.
485        """
486        print '<FORM METHOD="post" ACTION="%s" ENCTYPE="multipart/form-data">' % CGI_SCRIPT_URL_PATH
487        print "<P>Please provide the location of the request file you wish to upload:"
488        print """&nbsp;<INPUT TYPE="file" NAME="uploadedFile" VALUE="" SIZE="40">
489                       <INPUT NAME="action" TYPE="hidden" VALUE="parseUploadedFile">
490                       <INPUT NAME="sessionID" TYPE="hidden" VALUE="%s">
491                       <INPUT TYPE="submit" NAME="submit" VALUE="Upload"></FORM><P>\n<FORM>""" % sessionID
492
493
494    def _displayMetadataForm(self, fileName, fileFormat, varList, globalMetadata):
495        """
496        Displays the metadata in the data file.
497        """
498        #print """<INPUT NAME="variable_1" TYPE="hidden" VALUE="pqn">"""
499        print """<P>Thank you for uploading your file to the NetCDF-NASA Ames convertor.
500               The following information has been extracted from the file:
501               <BR><B>Filename:     %s</B>
502               <BR><B>File format:  %s</B>
503               <P><B><FONT SIZE="+1">Variables:</FONT></B>
504               <BR>Select the variables that you wish convert (Default=ALL):<P>""" % (fileName, fileFormat)
505       
506        # Now print the variable list as a form
507        varCount=1
508        print '<BR><INPUT TYPE="hidden" NAME="selectionsMade" VALUE="complete">'
509        for var in varList:
510            longName, varID=var
511            varString=varID
512            displayVar="%s &nbsp;&nbsp;{%s}" % (longName, varID)
513            if varID in ("None", "", None):
514                varString=longName
515                displayVar=varString
516            print '<BR><INPUT TYPE="checkbox" NAME="variable_%s" VALUE="%s" CHECKED>%s</INPUT>' % (varCount, varString, displayVar)
517            #print "<BR>%s (%s)" % tuple(var) # prints var id and long_name
518            varCount=varCount+1
519       
520        outFileMap={"NetCDF":"NASA Ames", "NASA Ames":"NetCDF"}   
521        # Now print metadata
522        print """<P><BR><B><FONT SIZE="+1">Global Metadata</FONT></B>
523              <BR>The following global metadata will be written to your output %s file(s):<P>""" % outFileMap[fileFormat]
524             
525        print '<TABLE BORDER="0">'
526        maxSize=10
527        for item in globalMetadata:
528            key, value=item
529            if key=="VNAME":
530                continue
531                displayKey="VNAME Variables from NASA Ames (modify below to rename)"
532            elif key=="ANAME":
533                continue
534                if value!=None:
535                    displayKey="ANAME Auxiliary Variables from NASA Ames (modify below to rename)"
536                else:
537                    break
538            else:
539                displayKey=key
540               
541            print '<TR><TD WIDTH="25"><B>%s: </B>' % displayKey
542           
543            #print str(type(value))
544            if type(value)!=type(""):
545                # deal with list type by indexing each part
546                try:
547                    value=value.data
548                except:
549                    pass
550                   
551                partCount=1
552                lengthList=[len(str(i)) for i in value]
553                total=0
554                for i in lengthList: total=total+i
555                #print "<P>TOTAL:", total
556                if total<60: 
557                    # Put all on one line
558                    print "<BR>"
559                    separator=""
560                    sizeString="%s" % (max(lengthList)+5)
561                    inputType="textbox"
562                else:
563                    separator="<BR>"
564                    sizeString="100"
565                    inputType="textbox"
566                   
567                #print dir(value), value.data
568                for part in value:
569                    if key in ("VNAMEAAAAAAAAAAA", "ANAMEAAAAAAAA"): # if variable names
570                        partName="%s-RENAMED_%s" % (key, partCount)
571                    else:
572                        partName="%s_%s" % (key, partCount)
573                    part=str(part)                 
574                    print '%s<INPUT TYPE="%s" NAME="%s" VALUE="%s" SIZE="%s"/>' % (separator, inputType, partName, part, sizeString)
575                    partCount=partCount+1
576                print "</TD></TR>"
577               
578            else:
579                size=len(value)     
580                if size>100:
581                    inputType="textbox"
582                else:
583                    inputType="textbox"
584                print '<INPUT TYPE="%s" NAME="%s" VALUE="%s" SIZE="100"/></TD></TR>' % (inputType, key, value)
585            #print "<BR>%s = %s" % tuple(item) # prints name and value of metadata item
586        print "</TABLE>"
587
588
589
590    def _displayOutputPage(self, outputFilePaths):
591        """
592        Displays full HTML page with a link to the output file.
593        """
594        if len(outputFilePaths)==1:
595            file=outputFilePaths[0]
596            print "<P><B>Your output file is available at:</B>"
597            print """<P><A HREF="%s">%s</A><P>""" % (file, file) 
598        else:
599            print "<P><B>Your output files are available at:</B><P>"
600            for file in outputFilePaths:
601                print """<A HREF="%s">%s</A><BR>""" % (file, file) 
602       
603                     
604    def _displayFinalMessage(self, outputMessage=[]):
605        """
606        Prints an a message for the final page.
607        """
608        outputString=""
609        for i in outputMessage: outputString=outputString+"***LINEBREAK***"+str(i)
610        outputString=outputString.replace("<", "&LT;")
611        outputString=outputString.replace(">", "&GT;")
612        outputString=outputString.replace("***LINEBREAK***", "<P>")
613        outputString=outputString.replace("\n\n", "<P>")
614        outputString=outputString.replace("\n", "<BR>")
615       
616        print """<P>Thank you for using <B>%s</B>. You can now download your output file.
617                 <BR>Any output from the conversion package is printed below:
618                 <P><TABLE BORDER="1"><TR><TD BGCOLOR="#EEEEEE"><KBD>%s</KBD></TD></TR></TABLE><P>
619              """ % (PACKAGE_NAME, outputString)
620
621
622    def _displayFeatureOptions(self):
623        """
624        Prints the available Features in a table.
625        """   
626        pass
627       
628       
629    def _displayHorizontalDomainOptions(self, bounds):
630        """
631        Prints a form entry for specifying the horizontal domain.
632        """
633        (northernExtent, westernExtent, southernExtent, easternExtent)=bounds
634
635        # Horizontal Domain
636        print '<B>Horizontal Domain</B><P>'
637
638        print """<TABLE><TR><TD WIDTH="20%%"></TD><TD WIDTH="20%%"></TD>
639<TD WIDTH="20%%" ALIGN="CENTER"><INPUT TYPE="text" NAME="northernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Northern Extent </FONT></TD>
640<TD WIDTH="20%%"></TD><TD WIDTH="20%%"></TD></TR>
641<TR><TD><INPUT TYPE="text" NAME="westernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Western Extent </FONT></TD>
642<TD CLASS="tablestyle" 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>
643<TD ALIGN="RIGHT"><INPUT TYPE="text" NAME="easternExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Eastern Extent </FONT></TD>
644<TD></TD>
645<TR><TD></TD><TD></TD>
646<TD ALIGN="CENTER"><INPUT TYPE="text" NAME="southernExtent" VALUE="%s" SIZE="6"><FONT SIZE="-1"><BR> Southern Extent </FONT></TD>
647<TD></TD><TD></TD></TR></TABLE>
648<input type="button" value="Select from map"
649    onClick="newWindow('%s','window2',550,400);">
650<TABLE><TR><TD CLASS="tablestyle">
651<B>NOTE ABOUT THE JAVA MAP APPLET:</B> 
652<BR>1. The map will not work if you do not have Java enabled on your browser.
653<BR>2. This applet is known not to work on certain browsers: Mozilla, Konqueror.
654<BR>3. On some browsers you may have to select your subset twice before it registers.<P>
655</TD></TR></TABLE>""" % (northernExtent, westernExtent, easternExtent, southernExtent, MAP_APPLET_URL_PATH)
656
657        helpLink=os.path.join(WEB_EXTRAS_URL_PATH, "help_page.html#interpolation")
658        print """<P>[&nbsp;<A NAME="%s" onClick="help('%s')">Note about interpolation methods.</A>&nbsp;]<P>""" % (helpLink, helpLink)
659
660       
661    def _displayVerticalSpatialDomainOptions(self, options):
662        """
663        Prints a form entry for specifying the vertical domain.
664        """
665        print '<P><B>Vertical Domain</B><P><TABLE WIDTH="100%"><TR>'
666        for dsetNumber in range(1, self.numberOfDatasets+1):
667            (levels, vertical_units)=options[dsetNumber-1]
668
669            if type(levels)==type(""): levels=(levels,)
670            if len(levels)>3:
671                levboxheight=3
672            else:
673                levboxheight=len(levels)
674
675            print """<TD WIDTH="50%%">Levels<BR><SELECT MULTIPLE NAME="verticalDomain_%s"
676                  SIZE="%s" WIDTH="50" VALUE="%s">""" % (dsetNumber, levboxheight, levels[0])
677            levSelected=" SELECTED"
678            for level in levels:
679                print """<OPTION VALUE="%s"%s>%s</OPTION>""" % (level, levSelected, level)
680                levSelected=""
681            print "</SELECT>"
682            print '<INPUT NAME="verticalUnits" TYPE="hidden" VALUE="hPa">' 
683            print "</TD>"
684        print "</TR></TABLE>"
685
686
687    def _displayTemporalDomainMenus(self, startTime, endTime, intervalValue, intervalUnits, axisIndex):
688        """
689        Displays a set of menus for entering the date and time limits for this axis.
690        """ 
691        startTime=getDateTimeComponents(startTime)
692        endTime=getDateTimeComponents(endTime)
693        super_index_list=[]
694        index_list=[]
695       
696        # Get the bin list for all times
697        timeList=DateTimeManager.createList(startTime, endTime, (intervalValue, intervalUnits), listtype="tuple")
698        timeBins=DateTimeManager.getTimeBins(timeList)
699       
700        for i in range(len(startTime)):
701            index_list.append(timeBins[i].index(startTime[i]))
702        #super_index_list=super_index_list+index_list[:]+index_list[:]
703
704        # Insert javascript functions to do date checking.
705        #if len(super_index_list)==12:  super_index_list=super_index_list+[0,0,0,0,0,0,0,0,0,0,0,0]
706        #print jsFunctions.js_dateCheckFunctionGroup % tuple(super_index_list)     
707
708        # Temporal domain
709        #print '<P><B>Time</B><P><TABLE WIDTH="100%"><TR>'
710        #print '<INPUT NAME="timeIntervalUnits_%s" TYPE="hidden" VALUE="%s">' % (axisIndex, intervalUnits)
711        #print '<INPUT NAME="timeIntervalValue_%s" TYPE="hidden" VALUE="%s">' % (axisIndex, intervalValue)
712        #print '<TD WIDTH="50%">'
713        #print '<TABLE BORDER="1"><TR>'
714 
715        print '<TD COLSPAN="3"><TABLE BORDER="1">'
716        for part in ("low", "", "high"):
717           
718            if part in ("Dataset %s: Start time" % axisIndex, "End time"):
719                print '<TD COLSPAN="6">%s</TD>' % part
720            elif part=="":
721                print "<TR><TD>&nbsp;</TD></TR>"
722            else:
723                print '<TR>'
724                fieldFlag=""
725                count=0
726                for key in TIME_KEYS:
727                    if part=="text":
728                        print "<TD>%s</TD>" % key
729                    elif part in ("low", "high"):
730                        print """<TD><SELECT NAME="%s_%s.time.%s" %s onChange="checkDate('%s_%s')">""" % (axisIndex, 
731                                   part, key.lower(), fieldFlag, part, axisIndex)
732                        if key=="year":
733                            timeFormat="%.4d"
734                        else:
735                            timeFormat="%.2d"
736
737                        for item in timeBins[count]:
738                            timeItem=timeFormat % item
739                            print """<OPTION VALUE="%s">%s</OPTION>""" % (timeItem, timeItem)
740               
741                        print "</SELECT></TD>"
742                        count=count+1
743
744                print "</TR>"
745        print "</TABLE></TD>"
746
747        #print "</TR></TABLE><P>"
748        # Call the javascript to update the date field at start
749        #print """<SCRIPT LANGUAGE="Javascript">resetAllDates(%s)</SCRIPT>""" % (dsetNumber-1)   
750       
751
752
753       
754    def DEPRACATED_displayTemporalDomainOptions(self, options):
755        """
756        Prints a form entry for specifying the temporal domain.
757        """ 
758        # timeDict holds time list dictionaries for start and end times,
759        # time units and time interval for each dataset
760        timeDict={}
761        for dsetNumber in range(1, self.numberOfDatasets+1):
762            (start_time, end_time, (intervalValue, intervalUnits))=options[dsetNumber-1]
763            timeDict["dataset_%s" % dsetNumber]=(start_time, end_time, intervalValue, intervalUnits) 
764 
765        super_index_list=[]
766        timeBins={}
767        for dsetNumber in range(1, self.numberOfDatasets+1):
768            (start_time, end_time, intervalValue, intervalUnits)=timeDict["dataset_%s" % dsetNumber]
769            index_list=[]
770            # Get the bin list for all times
771            timeList=DateTimeManager.createList(start_time, end_time, (intervalValue, intervalUnits), listtype="tuple")
772            timeBins[dsetNumber]=DateTimeManager.getTimeBins(timeList)
773            for i in range(len(start_time)):
774                index_list.append(timeBins[dsetNumber][i].index(start_time[i]))
775            super_index_list=super_index_list+index_list[:]+index_list[:] 
776
777        # Insert javascript functions to do date checking.
778        if len(super_index_list)==12:  super_index_list=super_index_list+[0,0,0,0,0,0,0,0,0,0,0,0]
779        print jsFunctions.js_dateCheckFunctionGroup % tuple(super_index_list)     
780
781        # Temporal domain
782        print '<P><B>Time</B><P><TABLE WIDTH="100%"><TR>'
783        for dsetNumber in range(1, self.numberOfDatasets+1):
784            (intervalValue, intervalUnits)=timeDict["dataset_%s" % dsetNumber][2:]
785            (start_time, end_time)=timeDict["dataset_%s" % dsetNumber][:2]
786            print '<INPUT NAME="timeIntervalUnits_%s" TYPE="hidden" VALUE="%s">' % (dsetNumber, intervalUnits) 
787            print '<INPUT NAME="timeIntervalValue_%s" TYPE="hidden" VALUE="%s">' % (dsetNumber, intervalValue)
788            print '<TD WIDTH="50%">'
789            print '<TABLE BORDER="1"><TR>'
790
791            for part in ("Dataset %s: Start time" % dsetNumber, "start", "text", "end", "End time"):
792                if part in ("Dataset %s: Start time" % dsetNumber, "End time"):
793                    print '<TD COLSPAN="6">%s</TD>' % part
794                else:
795                  fieldFlag=""
796                  count=0
797                  for key in TIME_KEYS:
798                    if part=="text":
799                        print "<TD>%s</TD>" % key
800                    elif part in ("start", "end"):
801                        print """<TD><SELECT NAME="%s%s_%s" %s onChange="checkDate('%s_%s')">""" % (part, 
802                                   key, dsetNumber, fieldFlag, part, dsetNumber)
803                        if key=="year":
804                            timeFormat="%.4d"
805                        else:
806                            timeFormat="%.2d"
807
808                        for item in timeBins[dsetNumber][count]:
809                            timeItem=timeFormat % item
810                            print """<OPTION VALUE="%s">%s</OPTION>""" % (timeItem, timeItem)
811               
812                        print "</SELECT></TD>"
813                        count=count+1
814
815                print "</TR>"
816            print "</TABLE>"
817            print "</TD>"
818
819        print "</TR></TABLE><P>"
820        # Call the javascript to update the date field at start
821        print """<SCRIPT LANGUAGE="Javascript">resetAllDates(%s)</SCRIPT>""" % (dsetNumber-1)   
822       
823
824
825
826    def _chopUpSummary(self, summary):
827        """
828        Chops up the summary string returning a dictionary of items and a
829        list of keys for that dictionary ordered in an appropriate manner.
830        """
831        summaryDict={}
832        orderedKeys=[]
833        for line in summary.split("\n"):
834            if line.find(":")>-1:
835                (key, value)=line.strip().split(":\t")
836                summaryDict[key]=value
837                orderedKeys.append(key) 
838        return (summaryDict, orderedKeys)               
839
840
841    def _displayDatasetSummaryLine(self, summary, optionCategory, sessionID):
842        """
843        Takes a string containing a request summary and parses into suitable
844        HTML format. Prints a summary line for the current request - with clickable
845        links.
846        """
847        # Chop up the request information into a dictionary
848        summaryDict=self._chopUpSummary(summary)[0]
849               
850        # Set up the form for the actions bar to allow various useful functions
851        print """<FORM NAME="actions_bar" method="POST" action="%s">""" % CGI_SCRIPT_URL_PATH
852       
853        # Show return to start link
854        print '<A HREF="%s?action=clearRequest">Return to Start</A>' % CGI_SCRIPT_URL_PATH
855
856        # Get current number of Datasets before showing option of selecting number of datasets
857        # This sets the instance variable that is re-used everywhere from now on - clunky, I know!
858        """self.numberOfDatasets=int(summaryDict["numberOfDatasets"])"""       
859       
860        if sessionID in (None, "None"):
861            sidString=""
862        else:
863            sidString="&sessionID=%s" % sessionID
864       
865        # Show option for number of datasets if more than one allowed
866        """if MAX_NUM_DATASETS>1:
867            print ' | Number of Datasets <SELECT NAME="ndsets" onchange="redirect(this);">'
868           
869            for n in range(1, MAX_NUM_DATASETS+1):
870                if n==self.numberOfDatasets:
871                    print '<OPTION SELECTED VALUE="%s?numberOfDatasets=%s%s">%s</OPTION>' % (CGI_SCRIPT_URL_PATH, n, sidString, n)
872                else:
873                    print '<OPTION VALUE="%s?numberOfDatasets=%s%s">%s</OPTION>' % (CGI_SCRIPT_URL_PATH, n, sidString, n)
874                   
875            print "</SELECT>"  """
876       
877        # Link to view request summary
878        print '&nbsp;| <A HREF="%s?action=viewRequestSummary%s">View Current Request Summary</A>' % (CGI_SCRIPT_URL_PATH, sidString)
879       
880        # Allow save of request (XML format)
881        print ' | <A HREF="%s?action=saveRequest%s">Save Request (xml)</A>' % (CGI_SCRIPT_URL_PATH, sidString)
882       
883        # Allow upload of previous request (XML format)
884        print ' | <A HREF="%s?action=uploadRequest%s">Upload Request (xml)</A>' % (CGI_SCRIPT_URL_PATH, sidString)
885       
886        # Close actions bar form
887        print "</FORM>"
888                           
889        # Set up link to call each section from a URL link so that you
890        # can switch between one or two datasets
891        selfCaller="%s?" % CGI_SCRIPT_URL_PATH
892        firstCall=1
893        for key in summaryDict.keys():
894            if key=="targetPage":
895                extra="%s=%s" % (key, "INSERT_STAGE_HERE")
896            elif key=="numberOfDatasets":
897                pass
898            else:
899                extra="%s=%s" % (key, summaryDict[key])
900            if firstCall:
901                selfCaller=selfCaller+extra
902                firstCall=None
903            else:
904                selfCaller=selfCaller+"&"+extra
905        """     
906        if self.numberOfDatasets==1:
907            selectLink=selfCaller.replace("numberOfDatasets=1", "numberOfDatasets=2")
908            selectLink=selectLink.replace("targetPage=INSERT_STAGE_HERE", "")
909            # Temporary measure - send back to start if changed
910            selectLink="%s?numberOfDatasets=2" % CGI_SCRIPT_URL_PATH
911            print ' | <A HREF="%s">Select 2 datasets</A>' % selectLink
912        elif self.numberOfDatasets==2:
913            selectLink=selfCaller.replace("numberOfDatasets=2", "numberOfDatasets=1")
914            selectLink=selectLink.replace("targetPage=INSERT_STAGE_HERE", "")
915            # Temporary measure - send back to start if changed
916            selectLink="%s?numberOfDatasets=1" % CGI_SCRIPT_URL_PATH
917            print ' | <A HREF="%s">Deselect dataset 2</A>' % selectLink"""
918
919        # Begin an HTML table
920        """print '<TABLE WIDTH="100%"><TR class="tablerow"><TD COLSPAN="2">CURRENT REQUEST</TD></TR>'
921
922        print '<TR class="tablerow">'
923
924        # Get option category without number
925        optcat=optionCategory.split("_")[0]
926
927        for count in range(1, self.numberOfDatasets+1):
928          print '<TD WIDTH="50%%">Dataset %s: ' % count
929          if not summaryDict.has_key("datasetGroup_%s" % count):
930            print "None Specified"
931          elif summaryDict.has_key("datasetGroup_%s" % count):
932            displayString=' -&gt; <A HREF="%s&targetPage=%s">%s</A>' % (selfCaller, STAGES[0],
933                           summaryDict["datasetGroup_%s" % count])
934            print displayString.replace("INSERT_STAGE_HERE", STAGES[0])
935            if summaryDict.has_key("dataset_%s" % count) and optcat not in ("datasetGroup", "dataset"):
936                displayString=' -&gt; <A HREF="%s&targetPage=%s">%s</A>' % (selfCaller, STAGES[1],
937                               summaryDict["dataset_%s" % count])
938                print displayString.replace("INSERT_STAGE_HERE", STAGES[1])
939                if summaryDict.has_key("variable_%s" % count) and optcat not in ("datasetGroup", "dataset", "variable"):
940                    displayString=' -&gt; <A HREF="%s&targetPage=%s">%s</A>' % (selfCaller, STAGES[2],
941                                   summaryDict["variable_%s" % count])
942                    print displayString.replace("INSERT_STAGE_HERE", STAGES[2])
943                    if summaryDict.has_key("horizontalDomain_%s" % count):
944                        displayString=' -&gt; <A HREF="%s&targetPage=%s">%s</A>' % (selfCaller, STAGES[3],
945                                        "domain selection")
946                        print displayString.replace("INSERT_STAGE_HERE", STAGES[3])
947          print "</TD>"
948        print "</TR></TABLE>"
949        print "</I></B><P>"   """
950
951
952    def _sensibleTimeString(self, timeInSeconds):
953        """
954        Returns an appropriate string converting timeInSeconds to the most
955        readable units.
956        """
957        if timeInSeconds<1:
958            return "3 seconds"
959        if timeInSeconds<60:
960            return "%d seconds" % timeInSeconds
961        if timeInSeconds<(60*60):
962            (m, s)=divmod(timeInSeconds, 60)
963            return "%s mins %s secs" % (m, s)
964        else:
965            (m, s)=divmod(timeInSeconds, 60)
966            (h, m)=divmod(m, 60)
967            return "%s hrs %s mins" % (h, m)   
968
969
970    def _pathListFilter(self, pathList):
971        """
972        A sensible filter on path lists to a maximum of twenty.
973        """
974        if len(pathList)<21:
975            return pathList
976        else:
977            return pathList[:10]+["..."]+pathList[-10:]
978           
979
980    def _displayOutputFileList(self, pathList):
981        """
982        Prints links to all the files the user has requested.
983        """
984        print "<P><B>Your request has been processed.</B><HR><P>"       
985        print "<H3>Output information:</H3>"
986       
987        nfiles=len(pathList)
988        pathList=self._pathListFilter(pathList)
989        if nfiles<21:
990            displayedString="all the files produced"
991        else:
992            displayedString="the first 10 and the last 10 files, the rest follow the same file-naming system"
993       
994        plural="s have"
995        if nfiles==1: plural=" has" 
996        print "%s file%s been successfully written. The table below shows %s." % (nfiles, plural, displayedString)
997        print "<TABLE>"
998       
999        for file in pathList:
1000            localPath=file
1001            url=translateURI(localPath)
1002               
1003            if localPath=="...":
1004                print """<TR class="tablerow"><TD COLSPAN="3">...</TD>"""
1005            else:
1006                print """<TR class="tablerow">
1007                         <TD><B>%s</B></TD>
1008                         <TD><A HREF="%s">  Download  </A></TD>
1009                         <TD><A HREF="%s?fileURIList=%s&fileVariable_1.1=SELECT_AUTOMATICALLY">  Visualise  </A></TD>
1010                     </TR>""" % (url, url, GEOSPLAT_URL_PATH, localPath)
1011        print "</TABLE>"
1012        print '<P><A HREF="%s">Start a new request</A>.' % CGI_SCRIPT_URL_PATH
1013
1014       
1015    def _displayProcessingSection(self, estimatedDuration, estimatedVolume, sessionID):
1016        """
1017        Method to tell user that there job is underway with details of their selection.
1018        """
1019        print """<H3>Processing Information:</H3>
1020              <P>Your <B>job ID</B> is: %s
1021              <P>The estimated duration of your job is:  %s """ %  (sessionID, self._sensibleTimeString(estimatedDuration))
1022        print "<P>The estimated volume of your job is: %.2f MB" % ((estimatedVolume/1000000)+0.01)
1023        print "<P>Your extraction job is running...</P>"
1024       
1025        if estimatedDuration>60: 
1026            try:
1027                mailAddr=getUserEmail() 
1028                print "<P>You will be emailed at %s when the job has finished and the output is ready." % mailAddr       
1029            except:
1030                pass
1031               
1032        print "<P>Thank you for using the %s." % PACKAGE_NAME
1033        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>"
1034
1035
1036
1037    def _displayFileNameRuleOptions(self):
1038        """
1039        Prints the options for outputting to a single file or
1040        multiple files.
1041        """
1042        pass
1043       
1044
1045    def _displayRequestSummaryTable(self, summaryDict):
1046        """
1047        Prints a table summarising the current request.
1048        """
1049        print "<H3>The following is a summary of your request</H3>"
1050        print "<TABLE>"
1051        # Chop up the request information into a dictionary
1052        #(summaryDict, orderedKeys)=self._chopUpSummary(summary)
1053       
1054        d=summaryDict
1055        dsgKeys=d["datasetGroups"].keys()
1056        dsKeys=d["datasets"].keys()
1057        varKeys=d["variables"].keys()
1058        axisKeys=d["axes"].keys()
1059       
1060        dsgKeys.sort()
1061        dsKeys.sort()
1062        varKeys.sort()
1063        axisKeys.sort()
1064       
1065        template='<TR class="tablerow"><TD><B>%s%s</B></TD><TD>%s</TD></TR>'
1066       
1067        for dsg in dsgKeys:
1068            print template % ("Dataset Group ", dsg, d["datasetGroups"][dsg])       
1069           
1070            for ds in dsKeys:
1071                (dsgIndex, dsIndex)=re.match(r"^(\d+)\.(\d+)$", ds).groups()
1072                if dsg==dsgIndex:
1073                    print template % ("Dataset ", ds, d["datasets"][ds])
1074                   
1075                for var in varKeys:
1076                    (dsgIndex, dsIndex, varIndex)=re.match(r"^(\d+)\.(\d+)\.(\d+)$", var).groups()
1077                    if dsg==dsgIndex and ds=="%s.%s" % (dsgIndex, dsIndex):
1078                        print template % ("Variable ", var, d["variables"][var])
1079                        if d["outputFormats"].has_key(var):
1080                            print template % ("Output format ", var, d["outputFormats"][var])
1081
1082                        if d["datasetURIs"].has_key(var):
1083                            print template % ("Dataset URI ", var, d["datasetURIs"][var])                       
1084                       
1085                    for axis in axisKeys:
1086                        (dsgIndex, dsIndex, varIndex, axisIndex)=re.match(r"^(\d+)\.(\d+)\.(\d+)\.(\d+)$", axis).groups()
1087                        if (dsg==dsgIndex and ds=="%s.%s" % (dsgIndex, dsIndex)) and var=="%s.%s.%s" % (dsgIndex, dsIndex, varIndex):
1088                            print template % ("Axis ", axis, d["axes"][axis])
1089       
1090            print "<TR><TD>&nbsp;</TD></TR>"
1091
1092       
1093        # Now globals
1094        globalKeys=d["globals"].keys()
1095        globalKeys.sort()
1096       
1097        for key in globalKeys:
1098            print template % (key, "", d["globals"][key])
1099       
1100        print "</TABLE>"
1101       
1102
1103    def _displayConfirmationSection(self, summary):
1104        """
1105        Asks the user to confirm their request.
1106        """
1107        print '<P><INPUT TYPE="submit" NAME="confirm" VALUE="Confirm"> Click the "Confirm" button to fetch your request.<P>'
1108       
1109        self._displayRequestSummaryTable(summary) 
1110
1111        print """<P><INPUT TYPE="submit" NAME="confirm" VALUE="Confirm"> Click the "Confirm" button to fetch your request.
1112        <BR>If you wish to modify your request please press the <I>Back</I> button on your browser.<P>"""
1113        print "</FORM><P>"
1114       
1115       
1116    def _displayOperationOptions(self):
1117        """
1118        Prints a form entry for specifying the required operation.
1119        """
1120        pass
1121       
1122       
1123    def _displayOutputFormatOptions(self, options, sessionID):
1124        """
1125        Prints the available output format options in a form.
1126        """
1127        print """<P><INPUT TYPE="checkbox" NAME="multipleFileOutput">
1128               &nbsp;Use multiple output files [ this is the default large files as limited by the server ]."""
1129               
1130        print '<P>Format&nbsp;<SELECT NAME="outputFormat">'
1131        for format in options:
1132            print "<OPTION>%s</OPTION>" % format
1133        print "</SELECT>"
1134             
1135        print "&nbsp;&nbsp; Note that you should choose NetCDF format if you wish to visualise data."
1136        print '<P><A HREF="%s?action=saveRequest&sessionID=%s">Get Request XML only.</A>' % (CGI_SCRIPT_URL_PATH, sessionID) 
1137        print '<P><INPUT TYPE="submit" NAME="proceed" VALUE="Proceed"><P>'
1138        print "</FORM><P>"     
1139
1140
1141    def _displayProcessesTable(self):
1142        """
1143        Prints the Processes table of current dx processes running.
1144        """     
1145        pass
1146   
1147       
1148    def _displayUploadRequestOptions(self, sessionID):
1149        """
1150        Generates an upload box for the user to load their own request.
1151        The current request is then overwritten by the uploaded version.
1152        """
1153        """
1154        How might this work.
1155        At any point I can click [ Upload Old Request ] which is an XML file.
1156        It opens a dialogue box for browse and it is saved onto the server and
1157        is referenced as http://localhost/cgi-bin/dxcgi.py?uploadedRequest=something/or/other.xml
1158        Then the dx opens it and parses it in, keeping the sessionID but losing all else!
1159        NOTE: Needs a visible REQUEST_XML_DIR_LOCAL_PATH dir.
1160        """
1161        print '<FORM METHOD="post" ACTION="%s" ENCTYPE="multipart/form-data">' % CGI_SCRIPT_URL_PATH
1162        print "<P>Please provide the location of the request file you wish to upload:"
1163        print """&nbsp;<INPUT TYPE="file" NAME="uploadedFile" VALUE="" SIZE="40">
1164                       <INPUT NAME="action" TYPE="hidden" VALUE="parseUploadedFile">
1165                       <INPUT NAME="sessionID" TYPE="hidden" VALUE="%s">
1166                       <INPUT TYPE="submit" NAME="submit" VALUE="Upload"></FORM><P>""" % sessionID
1167
1168       
1169    def _displaySaveRequestOptions(self, requestString, sessionID):
1170        """
1171        Generates an XML version of the request and writes this to a file locally.
1172        Then the user is pointed to that file in the same way they would be a data
1173        file.
1174        NOTE: Needs a visible REQUEST_XML_DIR_LOCAL_PATH dir.
1175        """
1176        # Write the file to the REQUEST_XML_DIR_LOCAL_PATH
1177        xmlFileName=sessionID+".xml"
1178        xmlFile=open(os.path.join(REQUEST_XML_DIR_LOCAL_PATH, xmlFileName), "w")
1179        xmlFile.write(requestString) # =dataSubsetSpecifier file
1180        xmlFile.close()
1181       
1182        httpFilePath=os.path.join(REQUEST_XML_DIR_URL_PATH, xmlFileName)
1183       
1184        print "<P>You can download your request file from:"
1185        print '<P><A HREF="%s">%s</A><P>' % (httpFilePath, httpFilePath)
1186
1187
1188    def _displayReturnLine(self, sessionID):
1189        """
1190        Displays a link to return to request.
1191        """
1192        print '<P><A HREF="%s?sessionID=%s">Return to your current request</A><P>' % (CGI_SCRIPT_URL_PATH, sessionID)
1193       
1194
1195if __name__=="__main__":
1196    print "Testing DisplayManager.py..."
1197    DisplayManager()
Note: See TracBrowser for help on using the repository browser.