diff roundup/rest.py @ 5561:7aa7f779198b REST-rebased

Split all rest action into 2 type element uri and collection uri committer: Ralf Schlatterbeck <rsc@runtux.com>
author Chau Nguyen <dangchau1991@yahoo.com>
date Wed, 30 Jan 2019 10:26:33 +0100
parents 2cc07def1b3f
children 70df783c4c0b
line wrap: on
line diff
--- a/roundup/rest.py	Wed Jan 30 10:26:33 2019 +0100
+++ b/roundup/rest.py	Wed Jan 30 10:26:33 2019 +0100
@@ -14,56 +14,39 @@
 
 class RestfulInstance(object):
     """Dummy Handler for REST
-       WARNING: Very ugly !!!!, cleaned & better organized in progress (next commit)
     """
 
     def __init__(self, db):
         # TODO: database, translator and instance.actions
         self.db = db
 
-    def action_get(self, resource_uri, input):
-        # TODO: split this into collection URI and resource URI
-        class_name = resource_uri
-        try:
-            class_obj = self.db.getclass(class_name)
-            """prop_name = class_obj.labelprop()
-            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)
-                      ]
-            result = json.JSONEncoder().encode(result)
-            # result = `len(dict(result))` + ' ' + `len(result)`
-        except KeyError:
-            pass
-
-        try:
-            class_name, item_id = hyperdb.splitDesignator(resource_uri)
-            class_obj = self.db.getclass(class_name)
-            props = class_obj.properties.keys()
-            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)
-                      ]
-            # Note: is this a bug by having an extra indent in xmlrpc ?
-            result = json.JSONEncoder().encode(dict(result))
-        except hyperdb.DesignatorError:
-            pass
+    def get_collection(self, class_name, input):
+        class_obj = self.db.getclass(class_name)
+        prop_name = class_obj.labelprop()
+        result = [{'id': item_id, 'name': 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, None, item_id)
+                  ]
+        result = json.JSONEncoder().encode(result)
 
         return result
 
-    def action_post(self, resource_uri, input):
-        class_name = resource_uri
+    def get_element(self, class_name, item_id, input):
+        class_obj = self.db.getclass(class_name)
+        props = class_obj.properties.keys()
+        props.sort()  # sort properties
+        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)
+                  ]
+        result = json.JSONEncoder().encode(dict(result))
 
+        return result
+
+    def post_collection(self, class_name, input):
         if not self.db.security.hasPermission('Create', self.db.getuid(),
                                               class_name):
             raise Unauthorised('Permission to create %s denied' % class_name)
@@ -92,60 +75,64 @@
             raise xmlrpc.UsageError, message
         return result
 
-    def action_put(self, resource_uri, input):
+    def post_element(self, class_name, item_id, input):
+        raise NotImplementedError
+
+    def put_collection(self, class_name, input):
         raise NotImplementedError
 
-    def action_delete(self, resource_uri, input):
+    def put_element(self, class_name, item_id, input):
+        raise NotImplementedError
+
+    def delete_collection(self, class_name, input):
         # TODO: should I allow user to delete the whole collection ?
+        raise NotImplementedError
+
+    def delete_element(self, class_name, item_id, input):
         # TODO: BUG with DELETE without form data. Working with random data
         #       crash at line self.form = cgi.FieldStorage(fp=request.rfile, environ=env)
-        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):
+    def patch_collection(self, class_name, input):
+        raise NotImplementedError
+
+    def patch_element(self, class_name, item_id, input):
         raise NotImplementedError
 
     def dispatch(self, method, uri, input):
         print "METHOD: " + method + " URI: " + uri
         print type(input)
         pprint.pprint(input)
-
-        # PATH is split to multiple pieces
-        # 0 - rest
-        # 1 - resource
-        #
-        # 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: 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.
+
+        # PATH is split to multiple pieces
+        # 0 - rest
+        # 1 - resource
+
+        resource_uri = uri.split("/")[1]
+        input_data = ["%s=%s" % (item.name, item.value) for item in input]
+
         try:
-            output = getattr(self, "action_%s" % method.lower())(uri_path[1], input_form)
+            if resource_uri in self.db.classes:
+                output = getattr(self, "%s_collection" % method.lower())(resource_uri, input_data)
+            else:
+                class_name, item_id = hyperdb.splitDesignator(resource_uri)
+                output = getattr(self, "%s_element" % method.lower())(class_name, item_id, input_data)
+        except hyperdb.DesignatorError:
+            pass  # invalid URI
         except AttributeError:
-            raise NotImplementedError
+            raise NotImplementedError  # Error: method is invalid
 
-        print "Response Length: %s - Response Content (First 50 char): %s" %\
-              (len(output), output[:50])
+        print "Length: %s - Content(50 char): %s" % (len(output), output[:50])
         return output

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