comparison roundup/rest.py @ 5574:55f97de157e7 REST-rebased

Headers Added X-Count-Total for pagination of GET method, Parse X-HTTP-Method-Override from client, Parse Request Accept content-type from URL and Header committer: Ralf Schlatterbeck <rsc@runtux.com>
author Chau Nguyen <dangchau1991@yahoo.com>
date Wed, 30 Jan 2019 10:26:34 +0100
parents 89ae4ef34efe
children 7a7927643357
comparison
equal deleted inserted replaced
5573:89ae4ef34efe 5574:55f97de157e7
3 3
4 This module is free software, you may redistribute it 4 This module is free software, you may redistribute it
5 and/or modify under the same terms as Python. 5 and/or modify under the same terms as Python.
6 """ 6 """
7 7
8 import urlparse
9 import os
8 import json 10 import json
9 import pprint 11 import pprint
10 import sys 12 import sys
11 import time 13 import time
12 import traceback 14 import traceback
72 protocol = 'http' 74 protocol = 'http'
73 host = self.client.env['HTTP_HOST'] 75 host = self.client.env['HTTP_HOST']
74 tracker = self.client.env['TRACKER_NAME'] 76 tracker = self.client.env['TRACKER_NAME']
75 self.base_path = '%s://%s/%s/rest/' % (protocol, host, tracker) 77 self.base_path = '%s://%s/%s/rest/' % (protocol, host, tracker)
76 78
77 print self.base_path
78
79 def get_collection(self, class_name, input): 79 def get_collection(self, class_name, input):
80 if not self.db.security.hasPermission('View', self.db.getuid(), 80 if not self.db.security.hasPermission('View', self.db.getuid(),
81 class_name): 81 class_name):
82 raise Unauthorised('Permission to view %s denied' % class_name) 82 raise Unauthorised('Permission to view %s denied' % class_name)
83 class_obj = self.db.getclass(class_name) 83 class_obj = self.db.getclass(class_name)
85 result = [{'id': item_id, 'link': class_path + item_id} 85 result = [{'id': item_id, 'link': class_path + item_id}
86 for item_id in class_obj.list() 86 for item_id in class_obj.list()
87 if self.db.security.hasPermission('View', self.db.getuid(), 87 if self.db.security.hasPermission('View', self.db.getuid(),
88 class_name, 88 class_name,
89 itemid=item_id)] 89 itemid=item_id)]
90 self.client.setHeader("X-Count-Total", str(len(result)))
90 return 200, result 91 return 200, result
91 92
92 def get_element(self, class_name, item_id, input): 93 def get_element(self, class_name, item_id, input):
93 if not self.db.security.hasPermission('View', self.db.getuid(), 94 if not self.db.security.hasPermission('View', self.db.getuid(),
94 class_name, itemid=item_id): 95 class_name, itemid=item_id):
228 # 0 - rest 229 # 0 - rest
229 # 1 - resource 230 # 1 - resource
230 # 2 - attribute 231 # 2 - attribute
231 resource_uri = uri.split("/")[1] 232 resource_uri = uri.split("/")[1]
232 233
233 self.client.setHeader("Access-Control-Allow-Methods", 234 # if X-HTTP-Method-Override is set, follow the override method
234 "HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH") 235 method = self.client.request.headers.getheader('X-HTTP-Method-Override') or method
236
237 # get the request format for response
238 # priority : extension from uri (/rest/issue.json),
239 # header (Accept: application/json, application/xml)
240 # default (application/json)
241
242 # format_header need a priority parser
243 format_ext = os.path.splitext(urlparse.urlparse(uri).path)[1][1:]
244 format_header = self.client.request.headers.getheader('Accept')[12:]
245 format_output = format_ext or format_header or "json"
246
247 self.client.setHeader("Access-Control-Allow-Origin", "*")
235 self.client.setHeader("Access-Control-Allow-Headers", 248 self.client.setHeader("Access-Control-Allow-Headers",
236 "Content-Type, Authorization," 249 "Content-Type, Authorization, "
237 "X-HTTP-Method-Override") 250 "X-HTTP-Method-Override")
238 self.client.setHeader("Allow",
239 "HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH")
240 251
241 output = None 252 output = None
242 try: 253 try:
243 if resource_uri in self.db.classes: 254 if resource_uri in self.db.classes:
255 self.client.setHeader("Allow",
256 "HEAD, OPTIONS, POST, DELETE")
257 self.client.setHeader("Access-Control-Allow-Methods",
258 "HEAD, OPTIONS, POST, DELETE")
244 response_code, output = getattr(self, "%s_collection" % method.lower())( 259 response_code, output = getattr(self, "%s_collection" % method.lower())(
245 resource_uri, input) 260 resource_uri, input)
246 else: 261 else:
247 class_name, item_id = hyperdb.splitDesignator(resource_uri) 262 class_name, item_id = hyperdb.splitDesignator(resource_uri)
263 self.client.setHeader("Allow",
264 "HEAD, OPTIONS, GET, PUT, DELETE, PATCH")
265 self.client.setHeader("Access-Control-Allow-Methods",
266 "HEAD, OPTIONS, GET, PUT, DELETE, PATCH")
248 response_code, output = getattr(self, "%s_element" % method.lower())( 267 response_code, output = getattr(self, "%s_element" % method.lower())(
249 class_name, item_id, input) 268 class_name, item_id, input)
250 269
251 output = data_obj(output) 270 output = data_obj(output)
252 self.client.response_code = response_code 271 self.client.response_code = response_code
275 294
276 # out to the logfile, it would be nice if the server do it for me 295 # out to the logfile, it would be nice if the server do it for me
277 print 'EXCEPTION AT', time.ctime() 296 print 'EXCEPTION AT', time.ctime()
278 traceback.print_exc() 297 traceback.print_exc()
279 finally: 298 finally:
280 self.client.setHeader("Content-Type", "application/json") 299 if format_output.lower() == "json":
281 output = RoundupJSONEncoder().encode(output) 300 self.client.setHeader("Content-Type", "application/json")
301 output = RoundupJSONEncoder().encode(output)
302 else:
303 self.client.response_code = 406
304 output = ""
282 305
283 return output 306 return output
284 307
285 308
286 class RoundupJSONEncoder(json.JSONEncoder): 309 class RoundupJSONEncoder(json.JSONEncoder):

Roundup Issue Tracker: http://roundup-tracker.org/