source: cows_wps/trunk/cows_wps/renderer/proc_config_renderer.py @ 7095

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows_wps/trunk/cows_wps/renderer/proc_config_renderer.py@7095
Revision 7095, 8.4 KB checked in by astephen, 10 years ago (diff)

fixing up jobs page and moving renderer code into renderer package

Line 
1import logging
2import copy
3
4from cows_wps.utils.create_process_config import createProcessConfig
5
6from cows_wps.lib.ui.proc_config import ProcConfig
7from cows_wps.lib.ui.proc_config_convertor import ProcConfigConvertor
8#from cows_wps.utils.parse_capabilities_config import caps_config_dict
9
10from cows_wps.renderer.form_renderer import FormRenderer
11
12log = logging.getLogger(__name__)
13
14
15class ProcConfigRenderer(object):
16
17    def __init__(self):
18        # Set arg to be picked up by calling code to determine whether a bbox is needed/rendered
19        self.bbox_arg_found = False
20        self.pc = ProcConfig()
21
22    def renderProcConfig(self, proc):
23        pcc = ProcConfigConvertor()
24        proc_config = pcc.convertConfig(proc)
25        return self.renderProcessPage(proc_config)
26
27    def renderProcessPage(self, pc):
28        """
29        Takes a dictionary representing the process config.
30        Returns a list of HTML components.
31        """
32        resp = ["<div>"]
33
34        resp.extend( self.renderBlock("Process Information", pc["Process Information"]) )
35        resp.extend( self.renderInputs(pc["Inputs"]) )
36        resp.extend( self.renderBlock("Process Outputs", pc["Outputs"]) ) 
37
38        resp.append( "</div>\n" )
39        return resp
40
41    def renderBlock(self, id, items):
42
43        resp = ["<div>"]
44        resp.append( "<H3>%s</H3>\n" % id )
45
46        for k, v in items:
47               
48            resp.append( '<div style="width:200px;"><b>%s:</b></div><div style="position: relative; left:210px; top: -20px;">%s</div>\n' % (k, v) )
49
50        resp.append("</div>\n")
51        return resp
52
53    def renderInputs(self, items):
54        resp = ["<div>\n<H3>Process Inputs</H3>"]
55        resp.append( '<table border="1" style="position: relative; left: 30px;">\n' )
56
57        keys = ["Parameter name", "type", "item_type", "allowed_length", "possible_values"]
58        skeys = ["Parameter name", "Data type", "Is array?", "Permitted lengths", "Allowed values"]
59
60        resp.append("<tr>\n")
61        for (i, key) in enumerate(keys):
62            resp.append( '<td style="background:#FF9900"><b>%s</b></td>\n' % skeys[i] ) 
63
64        for (param_name, dct) in items: 
65
66            resp.append( '<tr>\n<td style="background:#FFFFFF">%s</td>\n' % param_name )
67
68            for key in keys[1:]:
69               
70                value = dct[key]
71                if key == "possible_values" and value != None:
72                    value = ", ".join(value)
73
74                if value != None: 
75                    resp.append( '<td style="background:#00FF00;">%s</td>\n' % value ) 
76                else:
77                    resp.append( '<td style="background:red;">-</td>\n' )
78
79            resp.append("</tr>\n")
80
81        resp.append("</table>\n")
82        resp.append("</div>\n")
83        return resp
84
85    def renderProcsViewTable(self):
86        """
87        Renders the table of all procs on the view page.
88        """
89        resp = """<table border="1">\n<tr>"""
90        headings = ("Process name", "Short description", "Full description", "Comments", 
91                    "Options")
92        for heading in headings:
93            resp += """<td width="17%%" style="background:#FF9900"><b>%s</b></td>\n""" % heading 
94        resp += "</tr>\n"
95
96        procs = self.pc.getProcList()
97        for (proc, long_name) in procs.items():
98            # Get config dict for this proc
99            proc_dict = createProcessConfig(proc)["Capabilities"]["globals"]
100
101            required_items = ("Title", "Abstract", "ProcessDescription")     
102            resp += """<tr>\n<td style="background: #FFFFFF;">%s</td>\n""" % proc
103
104            for req_item in required_items:
105                resp += """<td style="background: #FFFFFF;">%s</td>\n""" % proc_dict[req_item]
106
107            # Now add link to details and submit pages
108            resp += """<td style="background: #FFFFFF;"><a href="/submit/form?proc_id=%s">Submit job</a><br />
109                           <a href="/view/proc?proc_id=%s">View full details</a></td>\n""" % (proc, proc)
110
111            resp += "</tr>\n"
112
113        resp += "</table>\n" 
114        return resp
115
116    def renderProcSubmissionForm(self, proc, args):
117        """       
118        Renders a submission form for a proc.
119        Populates items with args dictionary if they exist.
120        """
121        pcc = ProcConfigConvertor()
122        proc_config = pcc.convertConfig(proc)
123        inputs = proc_config["Inputs"]
124
125        # Get form renderer
126        fm = FormRenderer()
127
128        resp = """Please complete the form below to submit a request to the CEDA Web Processing Service.
129                Note that some processes are restricted to registered users only.
130                Click the 'Submit' button to submit your request.<br><br>"""
131
132        resp += """\n\n <form action="/submit" onSubmit="return validateInputs();">
133                <input type="hidden" name="proc_id" id="proc_id" value="%s" />
134                <input type="hidden" id="_textarea_ids" name="_textarea_ids" value="" />
135                <table border="0">\n""" % proc
136
137        # Now render the inputs dict as a form
138        count = 0 
139        for (name, input) in inputs:
140
141            # Set colour style for row
142            count += 1
143            row_style = ("even_row", "odd_row")[count % 2]
144
145            # Start HTML for row
146            resp += """<tr class="%s"><td width="25%%"><b>%s</b></td><td width="30%%">\n""" % (row_style, name)
147
148            # Parse arguments from config
149            al = input["allowed_length"]
150            pv = input["possible_values"]
151            default = input.get("default", None)
152            opt = input.get("optional", False)
153            array_or_item = input["item_type"]
154
155            multiple = False
156            if array_or_item == "list":
157                multiple = True
158
159            tp = input["type"]
160
161            # Add a default instruction for this input type
162            instruction = ""
163            if opt == True:
164                instruction = "This input is optional."
165            if multiple == True:
166                instruction += " Multiple inputs are allowed."
167
168            # Now render them according to data type etc
169            if pv != None:
170                resp += fm.renderSelectList(name, values=pv, optional=opt, multiple=multiple)
171                n_items = "an item"
172                if multiple == True: n_items = "one or more items"
173                instruction += " Please select %s from the list." % n_items
174
175            elif tp == "bool":
176                resp += fm.renderRadioButton(name, is_boolean=True)
177                instruction += " Please select either true or false."
178           
179            elif tp in ("float", "int", "string", "datetime"):
180                if tp == "datetime":
181                    if args.has_key(name):
182                        # Use input arg sent in to form if received
183                        default = args[name]
184                    elif default:
185                        # Ensure time formatted correctly
186                        default = str(default).replace(" ", "T")
187       
188                    instruction += " Please insert a date/time field in the format <kbd><B>YYYY-MM-DDThh:mm:ss</B></kbd> such as <kbd>2009-01-01T00:00:00</kbd>."
189                else:
190                    # Use CGI arg if received
191                    if args.has_key(name):
192                        default = args[name]
193
194                    instruction += " Please insert a value of type: %s." % tp
195
196                resp += fm.renderTextInput(name, dtype = tp, optional = opt, default = default, multiple = multiple)
197           
198            elif tp == "filepath":
199                base_dir = input["basedir"] 
200                resp += fm.renderTypeAheadDirList(name, base_dir)
201                instruction += " Please type a file path on the CEDA file system. Click down to auto-fill with one of the options on the drop-down list."
202
203            elif tp == "bbox":
204                self.bbox_arg_found = True
205                extent = input.get("extent", False)
206                resp += fm.renderBBox(name, extent)
207                csv_extent = extent.replace("|", ", ")
208                instruction += " Please select a valid bounding box with the following geographical extent: %s" % csv_extent
209
210            resp += "</td><td>%s</td></tr>\n" % instruction
211     
212        count += 1
213        row_style = ("even_row", "odd_row")[count % 2] 
214        resp += '<tr class="%s"><td></td><td colspan="2"><input type="submit" value="Submit" /> Click this button when you are happy with your selections.</td></table>\n</form>\n' % row_style
215        return  fm.htmlify(resp)
Note: See TracBrowser for help on using the repository browser.