source: TI04-geosplat/trunk/pygsc/DisplayManager.py @ 798

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI04-geosplat/trunk/pygsc/DisplayManager.py@798
Revision 798, 18.1 KB checked in by astephen, 14 years ago (diff)

Latest working version with install method.
Can accept more than one file but doesn't combine variables yet.

  • Property svn:executable set to *
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 package client.
11
12"""
13
14# Import standard library modules
15import os, re
16
17# Import package modules
18from clientConfig import *
19from common import *
20
21class DisplayManager:
22    """
23    Class for displaying HTML output from the client.
24    """         
25   
26    def __init__(self):
27        """
28        Initialiser for display manager. Just gives a handle for the instance.
29        """
30        pass   
31       
32    def _displayHTTPHeader(self):
33        """
34        Prints the HTTP header.
35        """
36        print HTTP_HEADER
37       
38
39    def _displayHTMLHeader(self):
40        """
41        Prints the configured HTML header.
42        """
43        headfile=os.path.join(HTML_DIR_LOCAL_PATH, "header.html")
44        header=" ".join(open(headfile).readlines())
45        header=header.replace("PACKAGE_NAME", PACKAGE_NAME)
46        header=header.replace("WEB_EXTRAS_URL_PATH", WEB_EXTRAS_URL_PATH)
47        header=header.replace("LEFT_LOGO", os.path.join(LOGO_DIR, LEFT_LOGO))
48        header=header.replace("RIGHT_LOGO", os.path.join(LOGO_DIR, RIGHT_LOGO))
49        print header
50
51        # Now write user message if there is one:
52        if MESSAGE_TO_USERS!=None:
53            print """<CENTER><I>
54<FONT FACE="Arial, Helvetica, sans-serif" SIZE="+1" COLOR="RED">*** %s ***</FONT></I></CENTER><BR>""" % MESSAGE_TO_USERS
55
56
57    def _displayIntroduction(self):
58        """
59        Prints an introduction to the service.
60        """
61        print """<P>Welcome to the <B>%s</B>. This product is powered by Python,
62              CDAT and CSML.
63              """ % PACKAGE_NAME.replace("<BR>", " - ")
64        print """<P>Please provide a list of files (by full path on the GeoSPlAT
65              server network) that you would like to visualise. Please type each new file
66              a new line in the box below."""
67                     
68
69    def _displaySummaryLine(self, selectionList):
70        """
71        Prints a summary line of what has been selected so far.
72        """
73        print "<P><B>Selected so far:"
74        for item in selectionList:
75            print " -> %s" % item
76
77
78    def _displayLoginBar(self, username, loginStatus, loginMessage=""):
79        """
80        If security applies then display the login information.
81        """
82        if RESTRICTED_DATA:
83            statusMap={"out":"not logged in", "in":"logged in as %s" % username }
84            print "<P><B>Login status: </B>%s&nbsp;&nbsp;&nbsp;&nbsp;" % statusMap[loginStatus]
85            if len(loginMessage)>0:
86                print '<FONT COLOR="red">&nbsp;&nbsp;&nbsp;&nbsp;[ %s ]</FONT>' % loginMessage
87            if loginStatus=="out":
88                # Display a login form
89                print """<FORM NAME="loginForm" method="POST" action="%s">
90                      Username: <INPUT TYPE="text" SIZE="20" NAME="yousirnaim" VALUE="">
91                      Password: <INPUT TYPE="password" SIZE="10" NAME="parcewerd" VALUE="">
92                      <INPUT TYPE="submit" NAME="login" VALUE="Login"></FORM>""" % CGI_SCRIPT_URL_PATH
93            elif loginStatus=="in":
94                # Display a logout form
95                print """<FORM NAME="loginForm" method="POST" action="%s">
96                      <INPUT TYPE="submit" NAME="logout" VALUE="Logout"></FORM>""" % CGI_SCRIPT_URL_PATH                     
97                         
98       
99    def _displayHTMLFooter(self):
100        """
101        Prints the configured HTML footer.
102        """
103        footfile=os.path.join(HTML_DIR_LOCAL_PATH, "footer.html")
104        lines=open(footfile).read()
105        print lines % ("mailto:"+ADMIN_MAIL_ADDRESS)
106
107
108    def _displayErrorMessage(self, msg, sessionID=None, user=None):
109        """
110        Prints an error message, without a header or footer.
111        """
112        print "<P>An error has occurred with this application. The error message received is:<P>"
113        print "<P><B>%s</B>" % msg
114        print "<P>The administrator has been informed of this error and will look into it."
115        print """<P>You can try pressing the <I>Back</I> button to return to the previous page.
116                 Alternatively you can<P><A HREF="%s"><FONT SIZE="+1">restart your request</FONT></A>.""" % CGI_SCRIPT_URL_PATH
117       
118       
119    def _displayErrorPage(self, msg):
120        """
121        Prints an error page, including headers and footer.
122        """
123        self._displayHTTPHeader()
124        self._displayHTMLHeader()
125        self._displayErrorMessage(msg)
126
127       
128    def _displayMainTableHeader(self, sessionID):
129        """
130        Prints the header part of the main table used in the dx
131        web pages.
132        """
133        print '<TABLE WIDTH="100%"><TR>'
134               
135        print '<TABLE WIDTH="100%"><TR class="tablerow"><TD>SELECTIONS</TD></TR></TABLE>'
136        # Begin form in HTML output
137        print """<FORM NAME="splat_info" method="POST" action="%s">""" % CGI_SCRIPT_URL_PATH
138
139        print '<TABLE WIDTH="100%"><TR>'
140       
141        print '<INPUT NAME="sessionID" TYPE="hidden" VALUE="%s">' % sessionID   
142       
143       
144    def _displayMainTableFooter(self):
145        """
146        Prints the footer part of the main table used in the dx
147        web pages.
148        """
149        print "</TR></TABLE>"
150        print '<P><INPUT TYPE="submit" NAME="proceed" VALUE="Proceed"><P>'
151        print "</FORM><P>"
152
153
154    def _displayFileURIInput(self):
155        """
156        Displays the input box for the fileURIs.
157        """
158        print """<TD><TEXTAREA COLS="80" ROWS="6" SIZE="80" VALUE=""
159                 NAME="fileURIList"></TEXTAREA></TD>"""
160                 
161                 
162    def _displayVariableSelections(self, options, optionStrings):
163        """
164        Displays the variables that can be selected by users from each file.
165        """
166        print "<TD><P></TD></TR>"
167        print """<TR CLASS="tablerow"><TD><B>VARIABLE SELECTION PAGE:</B></TD></TR>"""
168        print """<TR><TD>Please select the variable that you would like GeoSPlAT to use.</TD></TR>"""
169        print "<TR><TD><BR></TD></TR>"
170       
171        # Decode the options stuff
172        fileCount=0
173       
174        checkedString=" CHECKED"
175        for option in options:
176            (fileURI, varIDs)=option
177            varLongNames=optionStrings[fileCount][1]
178           
179            print """<TR><TD CLASS="tablestyle"><B><FONT COLOR="black">FILE: %s</FONT></B><P>""" % fileURI
180            varCount=0
181           
182            for varID in varIDs:
183                print """<BR><INPUT TYPE="Checkbox" NAME="fileVariable_%s.%s" VALUE="%s"%s>
184                      &nbsp;%s
185                      """% (fileCount+1, varCount+1, varID, checkedString, varLongNames[varCount])                   
186                checkedString=""
187                varCount=varCount+1 
188               
189            fileCount=fileCount+1
190        print "</TD></TR>"
191               
192               
193    def _displayGraphicalOutputTypeSelections(self, optionCategories, options, optionStrings):
194        """
195        Displays the graphical output type options available to the user.
196        """
197        print "<TD><P></TD></TR>"
198        print """<TR CLASS="tablerow"><TD><B>GRAPHICAL OUTPUT SELECTION PAGE:</B></TD></TR>"""
199        print """<TR><TD>Please select the output that you would like GeoSPlAT to use for the chosen variable(s).</TD></TR>"""
200        print "<TR><TD><BR></TD></TR>" 
201       
202        radioName="graphicalOutputType"
203        # First go around display the single-variable options
204        print """<TR><TD CLASS="tablestyle"><B><FONT COLOR="black">SINGLE VARIABLE OPTIONS:</FONT></B>"""
205       
206        selectedFlag=" CHECKED"
207        optCounter=0
208        for option in options:
209            optCat=optionCategories[optCounter]
210            # Work out if option is single or multi-variable
211            numbers=(optCat.split("_"))[-1]
212            nVars=numbers.count("-")+1
213           
214            valueCounter=0
215           
216            if nVars==1:
217                for value in option:
218                    value=value+"_"+numbers
219                    valueString=optionStrings[optCounter][valueCounter]
220                    print """<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s"%s>%s</INPUT>""" % (radioName, value, selectedFlag, valueString)
221                    if selectedFlag:
222                        selectedFlag==None
223                    valueCounter=valueCounter+1
224                               
225            optCounter=optCounter+1
226                     
227        # Second time around display the multi-variable options
228        multiVarLine="""<TR><TD><B>MULTI-VARIABLE OPTIONS:</B>"""
229        optCounter=0
230        for option in options:
231            optCat=optionCategories[optCounter]
232            # Work out if option is single or multi-variable
233            numbers=(optCat.split("_"))[-1]
234            nVars=numbers.count("-")+1
235           
236            valueCounter=0
237           
238            if nVars>1:
239                if multiVarLine:
240                    print multiVarLine
241                    multiVarLine=None
242                   
243                for value in option:
244                    value=value+"_"+numbers
245                    valueString=optionStrings[optCounter][valueCounter]
246                    print """<BR><INPUT TYPE="radio" NAME="%s" VALUE="%s"%s>%s</INPUT>""" % (radioName, value, selectedFlag, valueString)
247                    if selectedFlag:
248                        selectedFlag==None
249                    valueCounter=valueCounter+1
250                               
251            optCounter=optCounter+1
252           
253        print "</TD></TR>"     
254   
255   
256    def _displayAnimationAxisOptions(self, optionCategories, options, optionStrings): 
257        """
258        Displays the animation axis options for the user to select.
259        """
260        print "<TD><P></TD></TR>"
261        print """<TR CLASS="tablerow"><TD><B>ANIMATION AXIS SELECTION PAGE:</B></TD></TR>"""   
262        print """<TR><TD>GeoSPlAT allows you to animate multiple frames.
263                 Please select the axes that you would like to use as:
264                 <UL>
265                 <LI>the X-axis on your plots
266                 <LI>the Y-axis on your plots
267                 <LI>the axis you would like to loop over in the animation.
268                 </UL></TD></TR>"""             
269        print "<TR><TD><BR></TD></TR>"
270               
271        print """<TR><TD><TABLE BORDER="2">"""
272       
273        print """<TR><TD>%s</TD><TD>%s</TD><TD>%s</TD><TD>%s</TD></TR>""" % \
274                   ("<B>Axis ID</B>", "<B>Long name</B>", "<B>Length</B>", "<B>Usage in plots</B>")
275       
276
277        checkedStrings=[[" CHECKED","",""], [""," CHECKED",""], ["",""," CHECKED"], ["","",""],["","",""],["","",""],["","",""]]
278        for i in range(len(options)):
279            print """<TR><TD>%s</TD><TD>%s</TD><TD>%s</TD><TD>%s&nbsp;%s&nbsp;%s&nbsp;</TD></TR>""" % \
280                  (options[i][0], optionStrings[i][0], options[i][1], 
281                  """<INPUT TYPE="Radio" NAME="axisLoopForAnimation" VALUE="%s"%s> Loop""" % (options[i][0], checkedStrings[i][0]), 
282                  """<INPUT TYPE="Radio" NAME="axisYForAnimation" VALUE="%s""%s> Y""" % (options[i][0], checkedStrings[i][1]),           
283                  """<INPUT TYPE="Radio" NAME="axisXForAnimation" VALUE="%s""%s> X""" % (options[i][0], checkedStrings[i][2]))
284       
285        print "</TABLE>"
286        print "</TD></TR>"
287
288
289    def _displayPlotConfigurations(self, optionCategories, options, optionStrings):
290        """
291        Displays the configuration options that can be selected by users for the chosen plot.
292        """
293        print "<TD><P></TD></TR>"
294        print """<TR CLASS="tablerow"><TD><B>GRAPHICAL CONFIGURATION PAGE:</B></TD></TR>"""
295        print """<TR><TD>Please select the options that you would like GeoSPlAT to use.</TD></TR>"""
296        print "<TR><TD><BR></TD></TR>"         
297       
298        onChangeJavaScriptFuncs={"File Format":"DO THESE ONE DAY"}
299       
300        print """<TR><TD><TABLE BORDERWIDTH="0">"""
301       
302        optCounter=0
303        for optcat in optionCategories:
304            optcat=optcat.split("_")[0]
305            optionList=options[optCounter]
306            if optionList==["UNAVAILABLE"]: 
307                optCounter=optCounter+1
308                continue
309           
310            onChangeString=" onCHANGEJLKSDFJDSLjfdslk"
311           
312            print """<TR><TD CLASS="tablestyle"><P><B>%s:</TD><TD><SELECT NAME="%s"%s>""" % (makeSpacesBetweenCaps(optcat), optcat, onChangeString)
313                     
314            valueCounter=0
315            selectedString=[" SELECTED"]+([""]*1000)
316           
317            for value in options[optCounter]:
318                valueString=optionStrings[optCounter][valueCounter]
319                   
320                print """<OPTION VALUE="%s"%s>%s</OPTION>""" % (value, selectedString[valueCounter], valueString)
321                valueCounter=valueCounter+1
322               
323            optCounter=optCounter+1     
324            print "</SELECT></TD></TR>"
325           
326           
327        print "</TABLE></TD></TR>"
328           
329           
330    def _displayProcessingWaiter(self):
331        """
332        Displays some text about having to wait.
333        """
334        print """<TR><TD CLASS="tablestyle"><B>RESULTS PAGE</B><P>Please wait while your visualisation is being generated.<P></TD>"""
335       
336
337    def _displayUploadForm(self, sessionID):
338        """
339        Displays a form entry for browsing the local system
340        to upload a file. UPLOAD_TEMP_DIR needs to be configured in
341        the clientConfig.py module.
342        """
343        print '<FORM METHOD="post" ACTION="%s" ENCTYPE="multipart/form-data">' % CGI_SCRIPT_URL_PATH
344        print "<P>Please provide the location of the request file you wish to upload:"
345        print """&nbsp;<INPUT TYPE="file" NAME="uploadedFile" VALUE="" SIZE="40">
346                       <INPUT NAME="action" TYPE="hidden" VALUE="parseUploadedFile">
347                       <INPUT NAME="sessionID" TYPE="hidden" VALUE="%s">
348                       <INPUT TYPE="submit" NAME="submit" VALUE="Upload"></FORM><P>\n<FORM>""" % sessionID
349
350
351
352    def _displayOutputPage(self, outputFilePaths):
353        """
354        Displays full HTML page with a link to the output file.
355        """
356        if len(outputFilePaths)==1:
357            file=outputFilePaths[0]
358            print "<P><B>Your output file is available at:</B>"
359            print """<P><A HREF="%s">%s</A><P>""" % (file, file) 
360        else:
361            print "<P><B>Your output files are available at:</B><P>"
362            for file in outputFilePaths:
363                print """<A HREF="%s">%s</A><BR>""" % (file, file) 
364
365        if DATA_EXTRACTOR_URL_PATH not in (None, ""):
366            print '<P><A HREF="%s">Start new Data Extraction</A>.<P>' % DATA_EXTRACTOR_URL_PATH
367        print '<P><A HREF="%s">Re-start GeoSPlAT session</A>.<P>' % CGI_SCRIPT_URL_PATH
368       
369                     
370
371    def _chopUpSummary(self, summary):
372        """
373        Chops up the summary string returning a dictionary of items and a
374        list of keys for that dictionary ordered in an appropriate manner.
375        """
376        summaryDict={}
377        orderedKeys=[]
378        for line in summary.split("\n"):
379            if line.find(":")>-1:
380                (key, value)=line.strip().split(":\t")
381                summaryDict[key]=value
382                orderedKeys.append(key) 
383        return (summaryDict, orderedKeys)               
384
385
386    def _displayOutputFile(self, path):
387        """
388        Prints links to the file the user has requested.
389        """
390        print "<H3>Output information:</H3>"   
391        print """Your output file been successfully written and is now available at:
392              <A HREF="%s">%s</A>.""" % (path, path)
393        if path.split(".")[-1].lower()=="gif":
394            print """<P>Your output should also appear below when completed (Note: this may
395                  take longer than this web page takes to render).
396                  <P><IMG SRC="%s" BORDER="2" ALT="Your plot should appear here."><P>
397                  """ % path
398
399        if DATA_EXTRACTOR_URL_PATH not in (None, ""):
400            print '<P><A HREF="%s">Start new Data Extraction</A>.<P>' % DATA_EXTRACTOR_URL_PATH
401        print '<P><A HREF="%s">Re-start GeoSPlAT session</A>.<P>' % CGI_SCRIPT_URL_PATH
402
403       
404    def _displayProcessingSection(self, estimatedDuration, estimatedVolume, sessionID):
405        """
406        Method to tell user that there job is underway with details of their selection.
407        """
408        print """<H3>Processing Information:</H3>
409              <P>Your <B>job ID</B> is: %s
410              <P>The estimated duration of your job is:  %s """ %  (sessionID, self._sensibleTimeString(estimatedDuration))
411        print "<P>The estimated volume of your job is: %.2f MB" % (estimatedVolume/1000000)
412        print "<P>Your extraction is running...</P>"
413       
414        if estimatedDuration>60: 
415            try:
416                mailAddr=getUserEmail() 
417                print "<P>You will be emailed at %s when the job has finished and the output is ready." % mailAddr       
418            except:
419                pass
420               
421        print "<P>Thank you for using the %s." % PACKAGE_NAME
422        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>"
423       
424
425    def _displayRequestSummaryTable(self, summary):
426        """
427        Prints a table summarising the current request.
428        """
429        print "<H3>The following is a summary of your request</H3>"
430        print "<TABLE>"
431        # Chop up the request information into a dictionary
432        (summaryDict, orderedKeys)=self._chopUpSummary(summary)
433               
434        for key in orderedKeys:
435            print '<TR class="tablerow"><TD><B>%s</B></TD><TD>%s</TD></TR>' % (key, summaryDict[key])
436       
437        print "</TABLE>"
438       
439
440    def _displayConfirmationSection(self, summary):
441        """
442        Asks the user to confirm their request.
443        """
444        print '<INPUT NAME="action" TYPE="hidden" VALUE="createOutput">' 
445        print '<P><INPUT TYPE="submit" NAME="confirm" VALUE="Confirm"> Click the "Confirm" button to fetch your request.<P>'
446       
447        self._displayRequestSummaryTable(summary) 
448
449        print """<P><INPUT TYPE="submit" NAME="confirm" VALUE="Confirm"> Click the "Confirm" button to fetch your request.
450        <BR>If you wish to modify your request please press the <I>Back</I> button on your browser.<P>"""
451        print "</FORM><P>"
452
453
454    def _displayProcessesTable(self):
455        """
456        Prints the Processes table of current dx processes running.
457        """     
458        pass
459   
460       
461    def _displayUploadRequestOptions(self, sessionID):
462        """
463        Generates an upload box for the user to load their own request.
464        The current request is then overwritten by the uploaded version.
465        """
466        """
467        How might this work.
468        At any point I can click [ Upload Old Request ] which is an XML file.
469        It opens a dialogue box for browse and it is saved onto the server and
470        is referenced as http://localhost/cgi-bin/dxcgi.py?uploadedRequest=something/or/other.xml
471        Then the dx opens it and parses it in, keeping the sessionID but losing all else!
472        NOTE: Needs a visible REQUEST_XML_DIR dir.
473        """
474        print '<FORM METHOD="post" ACTION="%s" ENCTYPE="multipart/form-data">' % CGI_SCRIPT_URL_PATH
475        print "<P>Please provide the location of the request file you wish to upload:"
476        print """&nbsp;<INPUT TYPE="file" NAME="uploadedFile" VALUE="" SIZE="40">
477                       <INPUT NAME="action" TYPE="hidden" VALUE="parseUploadedFile">
478                       <INPUT NAME="sessionID" TYPE="hidden" VALUE="%s">
479                       <INPUT TYPE="submit" NAME="submit" VALUE="Upload"></FORM><P>""" % sessionID
480
481       
482    def _displaySaveRequestOptions(self, requestString, sessionID):
483        """
484        Generates an XML version of the request and writes this to a file locally.
485        Then the user is pointed to that file in the same way they would be a data
486        file.
487        NOTE: Needs a visible REQUEST_XML_DIR dir.
488        """
489        # Write the file to the REQUEST_XML_DIR
490        xmlFileName=sessionID+".xml"
491        xmlFile=open(os.path.join(REQUEST_XML_DIR, xmlFileName), "w")
492        xmlFile.write(requestString) # =dataSubsetSpecifier file
493        xmlFile.close()
494       
495        httpFilePath=os.path.join(HTTP_REQUEST_XML_DIR, xmlFileName)
496       
497        print "<P>You can download your request file from:"
498        print '<P><A HREF="%s">%s</A><P>' % (httpFilePath, httpFilePath)
499
500
501    def _displayReturnLine(self, sessionID):
502        """
503        Displays a link to return to request.
504        """
505        print '<P><A HREF="%s?sessionID=%s">Return to your current request</A><P>' % (CGI_SCRIPT_URL_PATH, sessionID)
506       
Note: See TracBrowser for help on using the repository browser.