comparison 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
comparison
equal deleted inserted replaced
5558:1bef1076ad12 5559:3d80e7752783
7 7
8 import json 8 import json
9 import pprint 9 import pprint
10 from roundup import hyperdb 10 from roundup import hyperdb
11 from roundup.cgi.templating import Unauthorised 11 from roundup.cgi.templating import Unauthorised
12 from roundup import xmlrpc
12 13
13 14
14 class RestfulInstance(object): 15 class RestfulInstance(object):
15 """Dummy Handler for REST 16 """Dummy Handler for REST
17 WARNING: Very ugly !!!!, cleaned & better organized in progress (next commit)
16 """ 18 """
17 19
18 def __init__(self, db): 20 def __init__(self, db):
19 # TODO: database, translator and instance.actions 21 # TODO: database, translator and instance.actions
20 self.db = db 22 self.db = db
23 # TODO: split this into collection URI and resource URI 25 # TODO: split this into collection URI and resource URI
24 class_name = resource_uri 26 class_name = resource_uri
25 try: 27 try:
26 class_obj = self.db.getclass(class_name) 28 class_obj = self.db.getclass(class_name)
27 """prop_name = class_obj.labelprop() 29 """prop_name = class_obj.labelprop()
28 result = [class_obj.get(item_id, prop_name) 30 result = [class_obj.get(item_id, prop_name)"""
29 for item_id in class_obj.list()
30 if self.db.security.hasPermission('View', self.db.getuid(),
31 class_name, prop_name, item_id)
32 ]
33 result = json.JSONEncoder().encode(result)"""
34 result = [{'id': item_id} 31 result = [{'id': item_id}
35 for item_id in class_obj.list() 32 for item_id in class_obj.list()
36 if self.db.security.hasPermission('View', self.db.getuid(), 33 if self.db.security.hasPermission('View',
37 class_name, None, item_id) 34 self.db.getuid(),
35 class_name,
36 None,
37 item_id)
38 ] 38 ]
39 result = json.JSONEncoder().encode(result) 39 result = json.JSONEncoder().encode(result)
40 #result = `len(dict(result))` + ' ' + `len(result)` 40 # result = `len(dict(result))` + ' ' + `len(result)`
41 except KeyError: 41 except KeyError:
42 pass 42 pass
43 43
44 try: 44 try:
45 class_name, item_id = hyperdb.splitDesignator(resource_uri) 45 class_name, item_id = hyperdb.splitDesignator(resource_uri)
46 class_obj = self.db.getclass(class_name) 46 class_obj = self.db.getclass(class_name)
47 props = class_obj.properties.keys() 47 props = class_obj.properties.keys()
48 props.sort() 48 props.sort()
49 result = [(prop_name, class_obj.get(item_id, prop_name)) 49 result = [(prop_name, class_obj.get(item_id, prop_name))
50 for prop_name in props 50 for prop_name in props
51 if self.db.security.hasPermission('View', self.db.getuid(), 51 if self.db.security.hasPermission('View',
52 class_name, prop_name, item_id) 52 self.db.getuid(),
53 class_name,
54 prop_name,
55 item_id)
53 ] 56 ]
54 # Note: is this a bug by having an extra indent in xmlrpc ? 57 # Note: is this a bug by having an extra indent in xmlrpc ?
55 result = json.JSONEncoder().encode(dict(result)) 58 result = json.JSONEncoder().encode(dict(result))
56 except hyperdb.DesignatorError: 59 except hyperdb.DesignatorError:
57 pass 60 pass
58 61
59 # print type(result)
60 # print type(dict(result))
61 return result 62 return result
62 # return json.dumps(dict(result)) 63
63 # return dict(result) 64 def action_post(self, resource_uri, input):
65 class_name = resource_uri
66
67 if not self.db.security.hasPermission('Create', self.db.getuid(),
68 class_name):
69 raise Unauthorised('Permission to create %s denied' % class_name)
70
71 class_obj = self.db.getclass(class_name)
72
73 # convert types
74 props = xmlrpc.props_from_args(self.db, class_obj, input)
75
76 # check for the key property
77 key = class_obj.getkey()
78 if key and key not in props:
79 raise xmlrpc.UsageError, 'Must provide the "%s" property.' % key
80
81 for key in props:
82 if not self.db.security.hasPermission('Create', self.db.getuid(),
83 class_name, property=key):
84 raise Unauthorised('Permission to create %s.%s denied' %
85 (class_name, key))
86
87 # do the actual create
88 try:
89 result = class_obj.create(**props)
90 self.db.commit()
91 except (TypeError, IndexError, ValueError), message:
92 raise xmlrpc.UsageError, message
93 return result
94
95 def action_put(self, resource_uri, input):
96 raise NotImplementedError
97
98 def action_delete(self, resource_uri, input):
99 # TODO: should I allow user to delete the whole collection ?
100 # TODO: BUG with DELETE without form data. Working with random data
101 class_name = resource_uri
102 try:
103 class_obj = self.db.getclass(class_name)
104 raise NotImplementedError
105 except KeyError:
106 pass
107
108 try:
109 class_name, item_id = hyperdb.splitDesignator(resource_uri)
110 print class_name
111 print item_id
112 self.db.destroynode(class_name, item_id)
113 result = 'OK'
114 except IndexError:
115 result = 'Error'
116 except hyperdb.DesignatorError:
117 pass
118
119 return result
120
121 def action_patch(self, resource_uri, input):
122 raise NotImplementedError
64 123
65 def dispatch(self, method, uri, input): 124 def dispatch(self, method, uri, input):
66 print "METHOD: " + method + " URI: " + uri 125 print "METHOD: " + method + " URI: " + uri
67 print type(input) 126 print type(input)
68 pprint.pprint(input) 127 pprint.pprint(input)
72 # 1 - resource 131 # 1 - resource
73 # 132 #
74 # Example: rest/issue - collection uri 133 # Example: rest/issue - collection uri
75 # Example: rest/issue573 - element uri 134 # Example: rest/issue573 - element uri
76 uri_path = uri.split("/") 135 uri_path = uri.split("/")
136 input_form = ["%s=%s" % (item.name, item.value) for item in input]
137 # TODO: process input_form directly instead of making a new array
138 # TODO: rest server
77 # TODO: use named function for this instead 139 # TODO: use named function for this instead
78 # TODO: check roundup/actions.py 140 # TODO: check roundup/actions.py
79 # TODO: if uri_path has more than 2 child, return 404 141 # TODO: if uri_path has more than 2 child, return 404
142 # TODO: custom JSONEncoder to handle other data type
143 # TODO: catch all error and display error.
80 output = "METHOD is not supported" 144 output = "METHOD is not supported"
81 if method == "GET": 145 if method == "GET":
82 output = self.action_get(uri_path[1], input) 146 output = self.action_get(uri_path[1], input_form)
83 elif method == "POST": 147 elif method == "POST":
84 pass 148 output = self.action_post(uri_path[1], input_form)
85 elif method == "PUT": 149 elif method == "PUT":
86 pass 150 output = self.action_put(uri_path[1], input_form)
87 elif method == "DELETE": 151 elif method == "DELETE":
88 pass 152 output = self.action_delete(uri_path[1], input_form)
89 elif method == "PATCH": 153 elif method == "PATCH":
90 pass 154 output = self.action_patch(uri_path[1], input_form)
91 else: 155 else:
92 pass 156 pass
93 157
94 print "Response Length: " + `len(output)` + " - Response Content (First 50 char): " + output[:50] 158 print "Response Length: %s - Response Content (First 50 char): %s" %\
159 (len(output), output[:50])
95 return output 160 return output

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