source: TI03-DataExtractor/branches/titania_install/pydxc/DisplayManager.py.20061013.clean2 @ 1610

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI03-DataExtractor/branches/titania_install/pydxc/DisplayManager.py.20061013.clean2@1709
Revision 1610, 67.9 KB checked in by astephen, 14 years ago (diff)

Latest live version on titania.

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