Mercurial > p > roundup > code
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): |
