Mercurial > p > roundup > code
diff roundup/rest.py @ 5559:3d80e7752783 REST-rebased
Added POST and DELETE
[[Ralf Schlatterbeck: Add *all* http methods in roundup_server.py as
done on the bugs.python.org branch]]
committer: Ralf Schlatterbeck <rsc@runtux.com>
| author | Chau Nguyen <dangchau1991@yahoo.com> |
|---|---|
| date | Wed, 30 Jan 2019 10:25:12 +0100 |
| parents | 1bef1076ad12 |
| children | 2cc07def1b3f |
line wrap: on
line diff
--- a/roundup/rest.py Tue Jan 29 15:27:37 2019 +0100 +++ b/roundup/rest.py Wed Jan 30 10:25:12 2019 +0100 @@ -9,10 +9,12 @@ import pprint from roundup import hyperdb from roundup.cgi.templating import Unauthorised +from roundup import xmlrpc class RestfulInstance(object): """Dummy Handler for REST + WARNING: Very ugly !!!!, cleaned & better organized in progress (next commit) """ def __init__(self, db): @@ -25,19 +27,17 @@ try: class_obj = self.db.getclass(class_name) """prop_name = class_obj.labelprop() - result = [class_obj.get(item_id, prop_name) - for item_id in class_obj.list() - if self.db.security.hasPermission('View', self.db.getuid(), - class_name, prop_name, item_id) - ] - result = json.JSONEncoder().encode(result)""" + result = [class_obj.get(item_id, prop_name)""" result = [{'id': item_id} for item_id in class_obj.list() - if self.db.security.hasPermission('View', self.db.getuid(), - class_name, None, item_id) + if self.db.security.hasPermission('View', + self.db.getuid(), + class_name, + None, + item_id) ] result = json.JSONEncoder().encode(result) - #result = `len(dict(result))` + ' ' + `len(result)` + # result = `len(dict(result))` + ' ' + `len(result)` except KeyError: pass @@ -48,19 +48,78 @@ props.sort() result = [(prop_name, class_obj.get(item_id, prop_name)) for prop_name in props - if self.db.security.hasPermission('View', self.db.getuid(), - class_name, prop_name, item_id) + if self.db.security.hasPermission('View', + self.db.getuid(), + class_name, + prop_name, + item_id) ] # Note: is this a bug by having an extra indent in xmlrpc ? result = json.JSONEncoder().encode(dict(result)) except hyperdb.DesignatorError: pass - # print type(result) - # print type(dict(result)) return result - # return json.dumps(dict(result)) - # return dict(result) + + def action_post(self, resource_uri, input): + class_name = resource_uri + + if not self.db.security.hasPermission('Create', self.db.getuid(), + class_name): + raise Unauthorised('Permission to create %s denied' % class_name) + + class_obj = self.db.getclass(class_name) + + # convert types + props = xmlrpc.props_from_args(self.db, class_obj, input) + + # check for the key property + key = class_obj.getkey() + if key and key not in props: + raise xmlrpc.UsageError, 'Must provide the "%s" property.' % key + + for key in props: + if not self.db.security.hasPermission('Create', self.db.getuid(), + class_name, property=key): + raise Unauthorised('Permission to create %s.%s denied' % + (class_name, key)) + + # do the actual create + try: + result = class_obj.create(**props) + self.db.commit() + except (TypeError, IndexError, ValueError), message: + raise xmlrpc.UsageError, message + return result + + def action_put(self, resource_uri, input): + raise NotImplementedError + + def action_delete(self, resource_uri, input): + # TODO: should I allow user to delete the whole collection ? + # TODO: BUG with DELETE without form data. Working with random data + class_name = resource_uri + try: + class_obj = self.db.getclass(class_name) + raise NotImplementedError + except KeyError: + pass + + try: + class_name, item_id = hyperdb.splitDesignator(resource_uri) + print class_name + print item_id + self.db.destroynode(class_name, item_id) + result = 'OK' + except IndexError: + result = 'Error' + except hyperdb.DesignatorError: + pass + + return result + + def action_patch(self, resource_uri, input): + raise NotImplementedError def dispatch(self, method, uri, input): print "METHOD: " + method + " URI: " + uri @@ -74,22 +133,28 @@ # Example: rest/issue - collection uri # Example: rest/issue573 - element uri uri_path = uri.split("/") + input_form = ["%s=%s" % (item.name, item.value) for item in input] + # TODO: process input_form directly instead of making a new array + # TODO: rest server # TODO: use named function for this instead # TODO: check roundup/actions.py # TODO: if uri_path has more than 2 child, return 404 + # TODO: custom JSONEncoder to handle other data type + # TODO: catch all error and display error. output = "METHOD is not supported" if method == "GET": - output = self.action_get(uri_path[1], input) + output = self.action_get(uri_path[1], input_form) elif method == "POST": - pass + output = self.action_post(uri_path[1], input_form) elif method == "PUT": - pass + output = self.action_put(uri_path[1], input_form) elif method == "DELETE": - pass + output = self.action_delete(uri_path[1], input_form) elif method == "PATCH": - pass + output = self.action_patch(uri_path[1], input_form) else: pass - print "Response Length: " + `len(output)` + " - Response Content (First 50 char): " + output[:50] + print "Response Length: %s - Response Content (First 50 char): %s" %\ + (len(output), output[:50]) return output
