99import pprint
1010from roundup import hyperdb
1111from roundup .cgi .templating import Unauthorised
12+ from roundup import xmlrpc
1213
1314
1415class RestfulInstance (object ):
1516 """Dummy Handler for REST
17+ WARNING: Very ugly !!!!, cleaned & better organized in progress (next commit)
1618 """
1719
1820 def __init__ (self , db ):
@@ -25,19 +27,17 @@ def action_get(self, resource_uri, input):
2527 try :
2628 class_obj = self .db .getclass (class_name )
2729 """prop_name = class_obj.labelprop()
28- 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)"""
30+ result = [class_obj.get(item_id, prop_name)"""
3431 result = [{'id' : item_id }
3532 for item_id in class_obj .list ()
36- if self .db .security .hasPermission ('View' , self .db .getuid (),
37- class_name , None , item_id )
33+ if self .db .security .hasPermission ('View' ,
34+ self .db .getuid (),
35+ class_name ,
36+ None ,
37+ item_id )
3838 ]
3939 result = json .JSONEncoder ().encode (result )
40- #result = `len(dict(result))` + ' ' + `len(result)`
40+ # result = `len(dict(result))` + ' ' + `len(result)`
4141 except KeyError :
4242 pass
4343
@@ -48,19 +48,78 @@ def action_get(self, resource_uri, input):
4848 props .sort ()
4949 result = [(prop_name , class_obj .get (item_id , prop_name ))
5050 for prop_name in props
51- if self .db .security .hasPermission ('View' , self .db .getuid (),
52- class_name , prop_name , item_id )
51+ if self .db .security .hasPermission ('View' ,
52+ self .db .getuid (),
53+ class_name ,
54+ prop_name ,
55+ item_id )
5356 ]
5457 # Note: is this a bug by having an extra indent in xmlrpc ?
5558 result = json .JSONEncoder ().encode (dict (result ))
5659 except hyperdb .DesignatorError :
5760 pass
5861
59- # print type(result)
60- # print type(dict(result))
6162 return result
62- # return json.dumps(dict(result))
63- # return dict(result)
63+
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
64123
65124 def dispatch (self , method , uri , input ):
66125 print "METHOD: " + method + " URI: " + uri
@@ -74,22 +133,28 @@ def dispatch(self, method, uri, input):
74133 # Example: rest/issue - collection uri
75134 # Example: rest/issue573 - element uri
76135 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
77139 # TODO: use named function for this instead
78140 # TODO: check roundup/actions.py
79141 # 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.
80144 output = "METHOD is not supported"
81145 if method == "GET" :
82- output = self .action_get (uri_path [1 ], input )
146+ output = self .action_get (uri_path [1 ], input_form )
83147 elif method == "POST" :
84- pass
148+ output = self . action_post ( uri_path [ 1 ], input_form )
85149 elif method == "PUT" :
86- pass
150+ output = self . action_put ( uri_path [ 1 ], input_form )
87151 elif method == "DELETE" :
88- pass
152+ output = self . action_delete ( uri_path [ 1 ], input_form )
89153 elif method == "PATCH" :
90- pass
154+ output = self . action_patch ( uri_path [ 1 ], input_form )
91155 else :
92156 pass
93157
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 ])
95160 return output
0 commit comments