source: cows_wps/trunk/cows_wps/lib/ui/proc_config.py @ 6125

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows_wps/trunk/cows_wps/lib/ui/proc_config.py@6125
Revision 6125, 8.2 KB checked in by astephen, 11 years ago (diff)

Got bounding box added to MIDAS extractors. And in doing so they will work for all.

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