source: cows_wps/trunk/cows_wps/controllers/jobs.py @ 7633

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

Fixes to bugs in responses when not logged in, and added datatypes as
list for GetWeatherStations?.

Line 
1import logging
2import re
3
4from pylons import request, response, session, tmpl_context as c
5from pylons.controllers.util import abort, redirect_to
6
7from cows_wps.renderer.ui_renderer import *
8from cows_wps.controllers import *
9from cows_wps.lib.ui.proc_config import *
10
11from cows_wps.model.managers import requestManager
12from cows_wps.process_handler.context.process_status import STATUS
13from cows_wps.process_handler.validate_arguments import parseDateTime
14from cows_wps.utils.common import *
15
16log = logging.getLogger(__name__)
17
18
19def checkValidJobStatus(status):
20    allowed_status_codes = [code for code in STATUS.__dict__.keys() if code[0] != "_"]
21    status = status.split("|")
22
23    for st in status:
24        if st not in allowed_status_codes:
25            return False
26
27    return status
28   
29   
30def checkValidJobType(jtype):
31    allowed_job_types = ["1", "2"]
32    job_types = jtype.split("|")
33
34    for jtype in job_types:
35        if jtype not in allowed_job_types:
36            return False
37
38    return job_types
39
40
41def checkValidOrderBy(order_by):
42    allowed = ["job_id", "user_id", "job_status", "job_type", "sub_time"]
43    new_allowed = []
44
45    for i in allowed:
46        new_allowed.append("%s_rev" % i)
47
48    allowed.extend(new_allowed)
49
50    if order_by not in allowed:
51        return False
52
53    return order_by
54
55   
56def toDateTime(tm):
57    try:
58        return parseDateTime(tm)
59    except:
60        return False
61   
62
63class JobsController(BaseController):
64
65    job_item_order = {"job_id_match": 0, "user_id_match": 1, "job_status": 2,
66                      "job_type": 3, "sub_before": 4, "sub_after": 4,
67                      "job_id": 0, "sub_time": 4}
68
69    filter_types = {"job_id_match": "regex", 
70                    "job_desc_match": "regex",
71            "job_type": "contains",
72            "job_status": "contains",           
73            "sub_after": "time:after",
74            "sub_before": "time:before",
75            "user_id_match": "regex",
76            }
77
78    default_args = {"start": 0,
79                    "n_records": 500,
80            "job_desc_match": None,
81            "job_id_match": None,
82            "job_type": None,
83            "job_status": None,
84            "sub_before": None,
85            "sub_after": None,
86            "user_id_match": None, # for admin only
87            "order_by": "sub_time_rev"}
88
89    arg_processers = {"start": int,
90                    "n_records": int,
91            "job_desc_match": str,
92            "job_id_match": str,
93            "job_type": checkValidJobType,
94            "job_status": checkValidJobStatus,
95            "sub_before": toDateTime,
96            "sub_after": toDateTime,
97            "user_id_match": str,
98            "order_by": checkValidOrderBy}
99
100
101    def index(self):
102        # Check if admin is True
103        admin = isAdminLoggedIn(request)
104
105        (args, bad_args) = self._parseArgs(admin = admin)
106
107        renderer = UIPageRenderer()
108
109        if admin == False:
110            try:
111                user_id = request.environ["REMOTE_USER"].split("/")[-1]
112                args["user_id_match"] = user_id
113            except:
114                return renderer.render("Jobs page", 
115                                [("Jobs page - login required", "The jobs page is only visible to a valid user or system administrator.  Please login.")])
116        else:
117            user_id = None
118
119#        return (str(args) + "----" + str(bad_args))
120        (filtered_jobs, total_matches) = apply(self._filterJobs, [], args)
121
122        renderer = UIPageRenderer()
123        return renderer.renderJobsPage(filtered_jobs, total_matches, args, bad_args, user_id = user_id, admin = admin)
124   
125   
126    def _parseArgs(self, admin = False):
127        args = {}
128        bad_args = {}
129   
130        for (key, default) in self.default_args.items():
131
132            if not admin and key == "user_id_match":
133                continue
134
135            value = None
136
137            if request.params.has_key(key):
138                value = str(request.params.getone(key).strip())
139
140                # If arg_check is False then bad input
141                arg_check = apply(self.arg_processers[key], [value])
142
143                if value == "":
144                    value = default
145                elif arg_check == False:
146                    bad_args[key] = value
147                    value = default
148                else:
149                    value = arg_check
150            else:
151                value = default
152           
153            args[key] = value
154           
155        return (args, bad_args)
156   
157
158    def _orderJobs(self, jobs, order_by):
159        reverse = False
160
161        if order_by.find("_rev") > -1:
162            order_by = order_by.replace("_rev", "")
163            reverse = True
164
165        indx = self.job_item_order[order_by] 
166        tmp_jobs = [(job[indx], job[:]) for job in jobs]
167        tmp_jobs.sort()
168
169        if reverse:
170            tmp_jobs.reverse()
171         
172        ordered_jobs = [i[1] for i in tmp_jobs]
173        return ordered_jobs
174   
175   
176    def _filterJobs(self, user_id_match, start, n_records, job_desc_match, job_id_match,
177                    job_type, job_status, sub_before, sub_after, order_by):
178        # Get all jobs at start
179        requests = requestManager.getAllRequest()
180       
181        # Define jobs as tuple of (job_id, user, status, job_type, created)
182        # And convert all unicodes
183        jobs = [[str(i) for i in (r.id, r.user_id, r.job.status, r.job.type, r.job.created)] for r in requests]
184         
185        for filtr in ("job_id_match", "job_type", "job_status", "sub_before", "sub_after", "user_id_match"):
186            jobs = self._filterBy(jobs, filtr, filter_value = vars()[filtr])
187       
188        total_matches = len(jobs)       
189        ordered_jobs = self._orderJobs(jobs, order_by)[start:(start + n_records)]
190        return (ordered_jobs, total_matches)
191   
192   
193    def _filterBy(self, jobs, filtr, filter_value):
194        # Represent jobs as lists of properties
195        if filter_value == None:
196            return jobs
197       
198        indx = self.job_item_order[filtr]
199        test_param = None
200        filter_type = self.filter_types[filtr]
201        filtered_jobs = []
202
203        for job in jobs:
204       
205            item = job[indx]
206       
207            if filter_type == "regex":
208                if not test_param:
209                    test_param = re.compile(filter_value)
210       
211                if test_param.search(item):
212                    filtered_jobs.append(job)
213           
214            elif filter_type.find("time:") == 0:
215                if not test_param:
216                    test_param = filter_value
217
218                item = parseDateTime(item.replace(" ", "T").split(".")[0])
219       
220                when = filter_type.split(":")[1].strip()
221  #              raise (str(item) + "nnnnnn" + str(test_param))
222                if when == "after":
223                    if item > test_param:
224                        filtered_jobs.append(job)
225           
226                elif when == "before":
227                    if item < test_param:
228                        filtered_jobs.append(job)
229           
230            elif filter_type == "equality":
231#                raise (str(filter_value) + "...." + str(item))
232                if filter_value == item:
233                    filtered_jobs.append(job)
234           
235            elif filter_type == "contains":
236#                raise str(str(item) + str(filter_value))
237                if item in filter_value:
238                    filtered_jobs.append(job)
239
240        return filtered_jobs
241
Note: See TracBrowser for help on using the repository browser.