source: cows_wps/trunk/cows_wps/renderer/ui_renderer.py @ 7115

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

more work on admin interface etc.

Line 
1import os
2
3from pylons import config, request, tmpl_context as c
4from routes import url_for
5
6from genshi.template import TemplateLoader
7from genshi.builder import * 
8from genshi import HTML
9
10from cows_wps.renderer.form_renderer import *
11
12#c.tester = "OOJOJ"
13
14
15class UIPageRenderer(object):
16    """
17    A set of rendering methods.
18    """
19
20    def __init__(self):
21        # Instantiate Genshi template loader
22        self.template_dir = config["wps.template_dir"]
23        self.templateLoader = TemplateLoader(self.template_dir, auto_reload=True)
24
25    def _htmlifyItems(self, items):
26        """
27        Ensures that template treats all content items as HTML.
28        """
29        new_items = []
30
31        for i in range(len(items)):
32            new_items.append((items[i][0], HTML(items[i][1])))
33
34        return new_items
35
36    def render(self, title, items, admin = False, bbox_required = False):
37        """
38        Renders the page using title and then a list of tuples of
39         (section_title, section_content).
40        """
41        tmpl_gen = self.templateLoader.load("ui_template.html")
42        # Make sure items are HTML and won't be escaped
43        items = self._htmlifyItems(items)
44        stream = tmpl_gen.generate(title = title, items = items, 
45                        wps_capabilities_url = "/wps?Service=WPS&Request=GetCapabilities&Format=text/xml",
46                        admin = admin, bbox_required = bbox_required)
47        return stream.render('xhtml')
48
49
50    def renderJobsPage(self, jobs, total_matches, args, bad_args, user_id, admin = False):
51        """
52        Renders jobs page.
53        if ``admin`` is True then this is an administrator who can view all user jobs,
54        and cancel them!
55        """
56        jobs_html = '<b>Total jobs matched: <span style="background: white; border: solid 1px; padding: 3px;">%d</span></b><br/><br/>' % total_matches
57        jobs_html += self._renderJobsTable(jobs, user_id, admin = admin)
58 
59        filter_html = "Please select the filtering options and press the 'Filter jobs' button to submit the new filter settings."
60
61        if len(bad_args.keys()) > 0:
62            msg = "Warning: the following arguments were provided with unknown values: <br/><br/>"
63
64            for (key, value) in bad_args.items():
65                msg += "%s = %s<br/>" % (key, value) 
66
67            filter_html += '<center><div id="incorrect_arguments" style="width: 600px; border-width: 0px; background: orange; color: white; font-weight: bold; padding: 3px;">%s</div></center>' % msg
68
69        filter_html += self._renderFilterOptions(args, admin = admin)
70
71 
72        items = [("Welcome to the Jobs Page", "The Jobs Page allows you to view current and previous jobs. Select the filter options to modify the records matched."),
73                 ("Filter the Job List", filter_html),
74                 ("Jobs", jobs_html)] 
75
76        return self.render("Jobs Page", items, admin = admin)
77
78
79    def _renderJobsTable(self, jobs, user_id = None, admin = False):
80        """
81        Renders and returns (as string) table of HTML jobs.
82        if ``user_id`` matches user in job list then allow view/download or cancel.
83        if ``admin`` is True then you can view/cancel any job.
84        """
85        if user_id == None and admin == False:
86            raise Exception("_renderJobsTable requires either user_id or admin arg to be set, neither is.")
87
88        html = """
89<table border="2">
90        <tr class="header_row">
91                <td>Request ID</td>
92                <td>Job type</td>
93                <td>User</td>
94                <td>Submission time</td>
95                <td>Job status</td>
96                <td>Action</td>
97        </tr>\n"""
98
99        count = 0
100
101        for  (req_id, user, status, job_type, created) in jobs:
102            created = created.split(".")[0]
103
104            # Set colour style for row
105            count += 1
106            row_style = ("even_row", "odd_row")[count % 2]
107
108            # Set action
109            action = ""
110
111            # Allow extra actions if user_id matches job user
112            if user_id == user or admin == True:
113
114                # Define jobsviewer page
115                status_url = "http://" + request.environ["HTTP_HOST"] + url_for(controller = 'status', requestId = req_id) 
116                job_viewer_url = url_for(controller = 'jobviewer') + "?status_url=" + status_url
117                action += '<a href="%s">View job info/outputs</a>' % job_viewer_url
118
119                # If running allow cancellation
120                if status in ("STARTED", "ACCEPTED"):
121                    cancel_url = url_for(controller = "user", action = "cancel", userId = user, jobId = req_id) 
122                    action += '<br/><a href="%s">Cancel this job</a>' % cancel_url
123                    row_style = "highlighted_row"
124
125            # HTML for row
126            row = '<tr class="%s"><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n' % (row_style, req_id, job_type, user, created, status, action)
127            html += row
128
129        html += "</table>"
130        return html
131
132
133    def _renderFilterOptions(self, args, admin = False):
134        """
135        Returns a string for the rendered HTML for filter form.
136        if ``admin` is True allow filtering on user id.
137        """
138        fr = FormRenderer()
139
140        filters = [("job_id_match", {"type": "text", "regex": "any", "text": "Job ID matches (regular expression)", "default": ""}),
141                   ("job_status", {"type": "list", "text": "Job Status", "default": "-- Please select --",
142                         "optional": True, "multiple": False,
143                         "option_names": ["COMPLETED", "FAILED", "RUNNING"],
144                         "option_values": ["COMPLETED", "FAILED", "STARTED|ACCEPTED"]}),
145                   ("job_type", {"type": "list", "text": "Job Type", "default": "-- Please select --", 
146                         "optional": True, "multiple": False,
147                         "option_values": ["1", "2"], "option_names": ["1", "2"]}), 
148                   ("sub_before", {"type": "text", "regex": "datetime", "text": 
149                         "Job submitted before (format: YYYY-MM-DDThh:mm:ss)", "default": ""}),
150                   ("sub_after", {"type": "text", "regex": "datetime", "text": 
151                         "Job submitted after (format: YYYY-MM-DDThh:mm:ss)", "default": ""}),
152                  ]
153
154        if admin == True:
155            filters.append( ("user_id_match", {"type": "text", "regex": "any", "text": "User ID matches (regular expression)", "default": ""}) )
156
157        html = '<form name="filter_form" action="jobs">'
158        for (id, fd) in filters:
159
160            input = "<br/>%s " % fd["text"] 
161
162            if id in args.keys():
163                value = args[id]
164                if value == None: value = ""
165            else:
166                value = fd["default"] 
167
168            if fd["type"] == "text":
169                input += fr.renderTextInput(id, fd["regex"], optional = True)
170
171            elif fd["type"] == "list":
172                selected_value = value
173                if type(selected_value) == type([1,2]): selected_value = value[0]
174                input += fr.renderSelectList(id, fd["option_values"], optional = fd["optional"], 
175                                             multiple = fd["multiple"], option_names = fd["option_names"],
176                                             selected = selected_value)
177                input += "<br/>"
178
179            html += "\n%s" % input
180
181        html += '<br/><br/>Click the button to re-load the page with these settings <input type="submit" value="Filter jobs" />'
182        html += '</form>'
183        return html
Note: See TracBrowser for help on using the repository browser.