Fixed a bug in the JSON templating engine.

This commit is contained in:
Jonathan LaCour
2010-11-17 10:01:08 -05:00
parent 93d42a7a4c
commit 3e2386cf9e
8 changed files with 51 additions and 39 deletions

View File

@@ -1,7 +1,7 @@
Metadata-Version: 1.0
Name: pecan
Version: 0.1dev
Summary: A WSGI object-dispatching web framework, in the spirit of TurboGears, only much much smaller, with many fewer dependancies.
Summary: A WSGI object-dispatching web framework, in the spirit of TurboGears, only much much smaller, with many fewer dependencies.
Home-page: http://github.com/cleverdevil/pecan
Author: Jonathan LaCour
Author-email: jonathan@cleverdevil.org

View File

@@ -6,6 +6,7 @@ pecan/decorators.py
pecan/hooks.py
pecan/jsonify.py
pecan/pecan.py
pecan/rest.py
pecan/routing.py
pecan/secure.py
pecan/templating.py

View File

@@ -1,4 +1,5 @@
WebOb >= 0.9.8
WebOb >= 1.0.0
WebCore >= 1.0.0
simplegeneric >= 0.7
Genshi >= 0.6
Kajiki >= 0.2.2
@@ -6,4 +7,5 @@ Mako >= 0.3
py >= 1.3.4
WebTest >= 1.2.2
Paste >= 1.7.5.1
PasteScript >= 1.7.3
PasteScript >= 1.7.3
formencode >= 1.2.2

View File

@@ -1,14 +1,13 @@
try:
from json import JSONEncoder, dumps
from json import JSONEncoder
except ImportError:
from simplejson import JSONEncoder, dumps
from simplejson import JSONEncoder
from datetime import datetime, date
from decimal import Decimal
from webob.multidict import MultiDict
from simplegeneric import generic
#
# exceptions
#
@@ -21,49 +20,58 @@ class JsonEncodeError(Exception):
# encoders
#
class BaseEncoder(JSONEncoder):
def is_saobject(self, obj):
return hasattr(obj, '_sa_class_manager')
def jsonify(self, obj):
return dumps(self.encode(obj))
def encode(self, obj):
def is_saobject(obj):
return hasattr(obj, '_sa_class_manager')
class GenericJSON(JSONEncoder):
def default(self, obj):
import pdb; pdb.set_trace()
if hasattr(obj, '__json__') and callable(obj.__json__):
return obj.__json__()
elif isinstance(obj, (date, datetime)):
return obj.isoformat()
elif isinstance(obj, Decimal):
elif isinstance(obj, (datetime.date, datetime.datetime)):
return str(obj)
elif isinstance(obj, decimal.Decimal):
return float(obj)
elif self.is_saobject(obj):
elif is_saobject(obj):
props = {}
for key in obj.__dict__:
if not key.startswith('_sa_'):
props[key] = getattr(obj, key)
return props
elif isinstance(obj, ResultProxy):
return dict(rows=list(obj), count=obj.rowcount)
elif isinstance(obj, RowProxy):
return dict(rows=dict(obj), count=1)
elif isinstance(obj, MultiDict):
return obj.mixed()
else:
try:
from sqlalchemy.engine.base import ResultProxy, RowProxy
if isinstance(obj, ResultProxy):
return dict(rows=list(obj), count=obj.rowcount)
elif isinstance(obj, RowProxy):
return dict(rows=dict(obj), count=1)
except:
pass
return obj
return JSONEncoder.default(self, obj)
#
# generic function support
#
encoder = BaseEncoder()
_default = GenericJSON()
@generic
def jsonify(obj):
return encoder.encode(obj)
return _default.default(obj)
class GenericFunctionJSON(GenericJSON):
def default(self, obj):
return jsonify(obj)
_instance = GenericFunctionJSON()
def encode(obj):
return dumps(jsonify(obj))
if isinstance(obj, basestring):
return _instance.encode(obj)
try:
value = obj['test']
except TypeError:
if not hasattr(obj, '__json__') and not is_saobject(obj):
raise JsonEncodeError('Your Encoded object must be dict-like.')
except:
pass
"""Return a JSON string representation of a Python object."""
return _instance.encode(obj)

View File

@@ -5,6 +5,7 @@ from pecan import request
class RestController(object):
# TODO: implement the following:
# - get, new, edit, post_delete, get_delete
# - implement the "_method" parameter
# - see: http://turbogears.org/2.1/docs/modules/tgcontroller.html
@expose()

View File

@@ -34,8 +34,7 @@ class JsonRenderer(object):
def render(self, template_path, namespace):
from jsonify import encode
result = encode(namespace)
return result
return encode(namespace)
#

View File

@@ -169,6 +169,7 @@ class TestEngines(object):
@expose('json')
def index(self, argument=None):
assert argument == 'value'
return dict()
# arguments should get passed appropriately
app = TestApp(Pecan(RootController()))

View File

@@ -18,7 +18,7 @@ class TestRestController(object):
@expose('json')
def get_all(self):
return self.data
return dict(items=self.data)
@expose('json')
def post(self, value):
@@ -45,7 +45,7 @@ class TestRestController(object):
# test get_all
r = app.get('/things')
assert r.status_int == 200
assert r.body == dumps(ThingsController.data)
assert r.body == dumps(dict(items=ThingsController.data))
# test get_one
for i, value in enumerate(ThingsController.data):
@@ -81,4 +81,4 @@ class TestRestController(object):
# make sure it works
r = app.get('/things')
assert r.status_int == 200
assert len(loads(r.body)) == 4
assert len(loads(r.body)['items']) == 4