source: cows_wps/trunk/cows_wps/controllers/jobviewer.py @ 6909

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows_wps/trunk/cows_wps/controllers/jobviewer.py@6909
Revision 6909, 7.7 KB checked in by astephen, 10 years ago (diff)

updated it so it works. Needs finessing, doesn't show percent complete
yet.

Line 
1import os
2import re
3import glob
4import logging
5import urllib
6import xml.etree.ElementTree as ET
7
8from pylons import request, response, session, tmpl_context as c
9from pylons.controllers.util import abort, redirect_to
10from routes import url_for
11
12
13from cows.exceptions import *
14from cows.pylons.ows_controller import render_ows_exception
15
16from cows_wps.controllers import *
17from cows_wps import utils
18from cows_wps.renderer.ui_renderer import *
19from cows_wps.model.managers import requestManager
20from cows_wps.process_handler.context.process_context import ProcessContext
21from cows_wps.renderer import xml_renderer
22
23from cows_wps.utils.parse_wps_config import wps_config_dict
24from cows_wps.utils.parse_capabilities_config import caps_config_dict
25
26
27from cows_wps.model.managers import requestManager
28
29log = logging.getLogger(__name__)
30
31
32class JobviewerController(BaseController):
33
34
35    def index(self):
36        status_url = str(request.params.getone("status_url"))
37#        job_id = str(request.params.getone("job_id"))
38        getter = urllib.urlopen(status_url)
39        job_xml = getter.read()
40        getter.close()
41 
42        job_as_table = self._xmlToTable(job_xml)
43        job_xml_encoded = self._htmlifyXML(job_xml)
44        job_as_plots = "There are no plots available in the outputs of this job."
45
46        resp = """<div id="view_options" style="background: #EEF4FF; border: 2px outset blue; padding: 5px;">
47                <a href="javascript:switchViewTo('table_view');">Normal View</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"""
48
49        if self.status == "complete":
50            resp += """<a href="javascript:switchViewTo('xml_view');">View as XML</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
51                <a href="javascript:switchViewTo('plots_view');">View Plots (if available)</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"""
52
53        resp  += """
54</div>
55<div id="view_container" style="background: white; border: 2px outset blue; padding: 5px;">
56        <div id="view_contents">
57                <div id="table_view" style="visibility: visible; height: auto;"><div id="poll_info" class="poller"></div>%s</div>""" % (job_as_table)
58
59        if self.status == "complete":
60            resp += """
61                <div id="xml_view" style="visibility: hidden; height: 0px;">%s</div>
62                <div id="plots_view" style="visibility: hidden; height: 0px;">%s</div>
63</div>""" % (job_xml_encoded, job_as_plots)
64
65        elif self.status == "running":
66            jobviewer_url = url_for(controller='jobviewer', status_url = status_url)
67            base_url = "http://" + request.url[7:].split("/")[0]
68            full_url = base_url + jobviewer_url
69
70            resp += """<input type="hidden" id="poll_url" value="%s" />""" % status_url
71            resp += """<input type="hidden" id="jobviewer_url" value="%s" />""" % jobviewer_url
72#            resp += """<div id="poll_info">Polling here...</div>"""
73            resp += """<script type="text/javascript">
74        function init() {
75                pollWPS();
76        }
77
78</script>"""
79# </form>""" % (submitter_url, urllib.unquote(wps_request_url))
80
81        renderer = UIPageRenderer()
82        resp = renderer.render("WPS Job Information",
83                              [("Job: %s" % self.job_id, resp)])
84        return resp
85
86    def _resolveStatus(self, status_node):
87        snode = status_node.getchildren()[0].tag
88        mdict = {"Succeeded": "complete",
89                 "Failed": "failed",
90                 "Accepted": "running"}
91
92        for k,v in mdict.items():
93            if snode.find(k) > -1:
94                return v
95        else:
96            raise Exception("Could not match status tag.")
97
98    def _xmlToTable(self, xml):
99        "Chops up xml to get table of outputs."
100        self.node = ET.fromstring(xml)
101        self.namespace_ows = "http://www.opengeospatial.net/ows"
102        self.namespace = "http://www.opengeospatial.net/wps"
103
104        self.status = self._resolveStatus(self.node.find("{" + self.namespace + "}Status")) 
105
106        job_details = self.node.find("{" + self.namespace +  "}ProcessOutputs").find("{" + self.namespace +  "}Output").find("{" + self.namespace +  "}ComplexValue").find("{" + self.namespace +  "}WPSResponseDetails").find("{" + self.namespace +  "}JobDetails")
107
108        file_set_list = job_details.find("{" + self.namespace +  "}FileSet").getchildren()
109
110        items = ["JobID", "JobCompletionTimeDate", "JobDuration", "JobVolume", "RequestDescription",
111                 "RequestType"]
112        mapped_names = ["Job ID", "Completion Time", "Job Duration", "Output Size (Bytes)", 
113                        "Request Description", "Request Type"]
114
115        resp = "<h2>DETAILS</h2>"
116        resp += "Need to realise that in costonly response we have JobCompletionTimeDate empty because it hasn't run yet!<br><br>"
117
118        self.job_id = job_details.find("{" + self.namespace + "}JobID").text
119
120        for (i, item) in enumerate(items):
121            x = job_details.find("{" + self.namespace +  "}" + item).text
122            if type(x) != str: x = "Undefined"
123            resp += "<b>%s</b> = %s<br>" % (mapped_names[i], x.strip())
124
125        file_items = ["FileSize"]
126        mapped_file_items = ["File Size (Bytes)"]
127
128        resp += "<h2>OUTPUTS</h2>The following file outputs are available from your job.<br>"
129        for fnode in file_set_list:
130
131            furl = fnode.find("{" + self.namespace +  "}FileURL").text
132            fname = furl.split("/")[-1]
133            len_fname = len(fname)
134
135            p = 70
136            padding = p - len_fname
137            if padding < 0: padding = 0
138
139            resp += ('<br><kbd>%s [<a href="%s">Download</a>]</kbd>' + (padding * "&nbsp;")) % (fname, furl)
140
141            for (i, file_item) in enumerate(file_items):
142                x = fnode.find("{" + self.namespace +  "}" + file_item).text
143                resp += '%s Bytes' % x
144
145        return resp
146
147
148    def _htmlifyXML(self, xml):
149        "Returns html string that will make XML look ok on HTML page."
150        xml1 = xml.replace("<", "&lt;").replace(">", "&gt;").replace("\n", "<br>")
151
152        def retag(x): return x.replace("<", "&lt;").replace(">", "&gt;")
153
154        open_and_close = re.compile("^<([^/]+?)>.*?</\1>$")
155        open = re.compile("^<([^/]+)>$")
156        close = re.compile("^</(.+?)>$")
157        empty = re.compile("^<(.+?)/>$")
158        bad = re.compile("^</(.+?)>\s*<([^/]+)>$")
159
160        lines = [i.strip() for i in xml.split("\n")]
161
162        spant = '%s<span style="color: #%s;">%s</span><br>'
163        x = ""
164        pad = 0
165        pc = "&nbsp;" * 4
166
167        for line in lines:
168
169            colour = pad * 50000 
170            col = ("000000" + hex(colour).split("x")[-1])[-6:]
171            line2 = retag(line)
172
173            open_and_close_m = open_and_close.match(line)
174            open_m = open.match(line) 
175            close_m = close.match(line)
176            empty_m = empty.match(line)
177            bad_m = bad.match(line)
178
179            if line == lines[0]:
180                line = spant % (pc * pad, "0000ff", line2)
181                pad += 1
182            elif bad_m:
183                (first, second) = bad_m.groups()[:2]
184                pad -= 1
185                line1 = spant % (pc * pad, "%s" % col, "&lt;/%s&gt;" % first)
186                line2 = spant % (pc * pad, "%s" % col, "&lt;%s&gt;" % second)
187                line = line1 + line2
188                pad += 1
189            elif open_m:
190                line = spant % (pc * pad, "%s" % col, line2) 
191                pad += 1
192            elif close_m:
193                pad -= 1
194                line = spant % (pc * pad, "%s" % col, line2)
195            elif open_and_close_m:
196                line = spant % (pc * pad, "%s" % col, line2)
197            elif empty_m:
198                line = spant % (pc * pad, "%s" % col, line2)
199            else:
200                line = spant % (pc * pad, "0000ff", line2)
201
202            x += line
203
204        return x
205
206
Note: See TracBrowser for help on using the repository browser.