diff --git a/roa/README.txt b/roa/README.txt new file mode 100644 index 0000000..d95ae0a --- /dev/null +++ b/roa/README.txt @@ -0,0 +1,23 @@ +============================== +Resource-oriented Architecture +============================== + + ($Id$) + + >>> from zope import component + >>> from zope.publisher.browser import TestRequest + + +Providing object data in JSON format +==================================== + + >>> class Demo(object): + ... def __init__(self, name): + ... self.name = name + + >>> from cybertools.roa.json import JSONView + + >>> obj = Demo('test') + >>> jsv = JSONView(obj, TestRequest()) + >>> jsv() + '{"name": "test"}' diff --git a/roa/__init__.py b/roa/__init__.py new file mode 100644 index 0000000..38314f3 --- /dev/null +++ b/roa/__init__.py @@ -0,0 +1,3 @@ +""" +$Id$ +""" diff --git a/roa/json.py b/roa/json.py new file mode 100644 index 0000000..2fd1a73 --- /dev/null +++ b/roa/json.py @@ -0,0 +1,40 @@ +# +# Copyright (c) 2009 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Adapter(s)/view(s) for providing object attributes and other data in JSON format. + +$Id$ +""" + +from cybertools.util import json + + +class JSONView(object): + + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self): + return json.dumps(self.context.__dict__) + + def traverse(self, name): + # To be implemented by subclass + print '*** traversing', self.context, name + return None diff --git a/roa/tests.py b/roa/tests.py new file mode 100755 index 0000000..f8757f3 --- /dev/null +++ b/roa/tests.py @@ -0,0 +1,30 @@ +#! /usr/bin/python + +""" +Tests for the 'cybertools.roa' (Resource-oriented Architecture) package. + +$Id$ +""" + +import unittest, doctest +from zope.testing.doctestunit import DocFileSuite +from zope import component +from cybertools.roa import json + + +class Test(unittest.TestCase): + "Basic tests for the rest package." + + def testBasicStuff(self): + pass + + +def test_suite(): + flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS + return unittest.TestSuite(( + unittest.makeSuite(Test), + DocFileSuite('README.txt', optionflags=flags), + )) + +if __name__ == '__main__': + unittest.main(defaultTest='test_suite') diff --git a/roa/traversal.py b/roa/traversal.py new file mode 100644 index 0000000..fbabd4f --- /dev/null +++ b/roa/traversal.py @@ -0,0 +1,52 @@ +# +# Copyright (c) 2009 Helmut Merz - helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +IPublishTraverse adapter that checks the 'Accept' header. + +$Id$ +""" + +from zope.app.container.traversal import ItemTraverser +from zope import component + + +jsonMimeTypes = ('application/json',) + + +class CheckJSONTraverser(ItemTraverser): + + def publishTraverse(self, request, name): + if self.isJSONRequest(request): + return self.jsonTraverse(request, name) + return self.defaultTraverse(request, name) + + def isJSONRequest(self, request): + return request.get('CONTENT_TYPE') in jsonMimeTypes + + def jsonTraverse(self, request, name): + item = self.context.get(name) + if item is not None: + return item + # TODO: specify provides=IJSONView + view = component.getMultiAdapter((self.context, request), name='json') + if view is None: + return self.defaultTraverse(request, name) + return view.traverse(name) + + def defaultTraverse(self, request, name): + return super(CheckAcceptTraverser, self).publishTraverse(request, name) diff --git a/roa/z2/__init__.py b/roa/z2/__init__.py new file mode 100644 index 0000000..38314f3 --- /dev/null +++ b/roa/z2/__init__.py @@ -0,0 +1,3 @@ +""" +$Id$ +""" diff --git a/roa/z2/traversal.py b/roa/z2/traversal.py new file mode 100644 index 0000000..21a5b7d --- /dev/null +++ b/roa/z2/traversal.py @@ -0,0 +1,32 @@ +# +# Copyright (c) 2009 Helmut Merz - helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +""" +IPublishTraverse adapter for Zope 2 that checks the 'Accept' header. + +$Id$ +""" + +from ZPublisher.BaseRequest import DefaultPublishTraverse +from cybertools.roa.traversal import CheckJSONTraverser as BaseTraverser + + +class CheckJSONTraverser(BaseTraverser, DefaultPublishTraverse): + + defaultTraverse = DefaultPublishTraverse.publishTraverse + browserDefault = DefaultPublishTraverse.browserDefault +