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

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

Merged with titania version.

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