From c63285f8bc0c6d57478005d458faf3b13b59329a Mon Sep 17 00:00:00 2001 From: helmutm Date: Tue, 8 Sep 2009 07:16:49 +0000 Subject: [PATCH] work in progress: REST/JSON handling git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@3543 fd906abe-77d9-0310-91a1-e0d9ade77398 --- roa/json.py | 49 +++++++++++++++++++++++++++++++++++---------- roa/traversal.py | 33 +++++++++++++++++------------- roa/z2/traversal.py | 17 +++++++++------- 3 files changed, 67 insertions(+), 32 deletions(-) diff --git a/roa/json.py b/roa/json.py index 9e6193b..bf2544c 100644 --- a/roa/json.py +++ b/roa/json.py @@ -22,6 +22,7 @@ Adapter(s)/view(s) for providing object attributes and other data in JSON format $Id$ """ +from zope.interface import implements from cybertools.util import json @@ -31,19 +32,45 @@ class JSONView(object): self.context = context self.request = request - def __call__(self): - return self.context.__name__ - return json.dumps(self.context.__dict__.keys()) + # application methods, to be implemented by subclass - def create(self, name): - print '*** create (PUT)', self.context, name - return self.context + def getData(self, **kw): + return {} - def put(self): - print '*** PUT', self.context - return self.context + def putData(self, data): + return True + + def createObject(self, name, data): + return True + + # protocol methods def get(self): print '*** GET', self.context - self.request.response.write('hello') - return self.context + self.setHeader() + return json.dumps(self.getData()) + + def put(self): + print '*** PUT', self.context, self.getBody() + self.setHeader() + result = self.putData(self.getBody()) + return json.dumps(dict(ok=result)) + + def create(self, name): + print '*** create (PUT)', self.context, name, self.getBody() + self.setHeader(201) + result = self.createObject(name, self.getBody()) + return json.dumps(dict(ok=result, id=name)) + + # helper methods + + def getBody(self): + inp = self.request.stdin + inp.seek(0) + return inp.read() + + def setHeader(self, status=None): + response = self.request.response + if status: + response.setStatus(status) + response.setHeader('Content-Type', 'application/json') diff --git a/roa/traversal.py b/roa/traversal.py index f429029..e89262f 100644 --- a/roa/traversal.py +++ b/roa/traversal.py @@ -30,33 +30,35 @@ jsonMimeTypes = ('application/json',) def isJSONRequest(request): - return request.get('CONTENT_TYPE') in jsonMimeTypes + return request.get('HTTP_ACCEPT').split(';', 1)[0] in jsonMimeTypes + #return request.get('CONTENT_TYPE') in jsonMimeTypes class CheckJSONTraverser(ItemTraverser): + def getChild(self, name): + # may be overwritten by subclass + return self.context.get(name) + def publishTraverse(self, request, name): if isJSONRequest(request): return self.jsonTraverse(request, name) return self.defaultTraverse(request, name) def jsonTraverse(self, request, name): - print '*** jsonTraverse', self.context, name - if request['TraversalRequestNameStack']: - return self.defaultTraverse(request, name) method = self.request['REQUEST_METHOD'] - print '*** traversing', self.context, name, method - item = self.context.get(name) - if item is None: - view = component.getMultiAdapter((self.context, request), name='json') - if view is None: - return self.defaultTraverse(request, name) + child = self.getChild(name) + print '*** traversing', method, self.context, name, child + if self.getTraversalStack(): + if child is None: + raise AttributeError(name) + return child + if child is None: if method == 'PUT': + view = component.getMultiAdapter((self.context, request), name='json') return view.create(name) - return self.defaultTraverse(request, name) - view = component.getMultiAdapter((item, request), name='json') - if view is None: - return self.defaultTraverse(request, name) + raise AttributeError(name) + view = component.getMultiAdapter((child, request), name='json') if method == 'PUT': return view.put() return view.get() @@ -68,3 +70,6 @@ class CheckJSONTraverser(ItemTraverser): if self.isJSONRequest(request): return self.context, ('@@json',) return super(CheckJSONTraverser, self).browserDefault(request) + + def getTraversalStack(self): + return self.request['TraversalRequestNameStack'] diff --git a/roa/z2/traversal.py b/roa/z2/traversal.py index 4e3bcc2..b934678 100644 --- a/roa/z2/traversal.py +++ b/roa/z2/traversal.py @@ -38,13 +38,16 @@ class CheckJSONTraverser(BaseTraverser, DefaultPublishTraverse): return DefaultPublishTraverse.browserDefault(self, request) -old_traverse = HTTPRequest.traverse +def install_traverse_patch(): -def traverse(self, *args, **kw): - if isJSONRequest(self): - self.maybe_webdav_client = 0 - old_traverse(self, *args, **kw) + base_traverse = HTTPRequest.traverse -HTTPRequest.traverse = traverse + def traverse(self, *args, **kw): + if isJSONRequest(self): + self.maybe_webdav_client = 0 + return base_traverse(self, *args, **kw) -print '***** HTTPRequest.traverse monkey patch installed.' + HTTPRequest.traverse = traverse + print '***** HTTPRequest.traverse monkey patch installed.' + +install_traverse_patch()