A few minor tweaks:

* Only require simplejson if we need to.
 * Improve upon parameter validation.
 * Add a redirect utility function.
 * Remove some print statements.
This commit is contained in:
Jonathan LaCour
2010-10-11 08:54:51 -04:00
parent b5bfe60e3e
commit 1bc441876b
6 changed files with 87 additions and 23 deletions

View File

@@ -1,7 +1,7 @@
from paste.urlparser import StaticURLParser
from paste.cascade import Cascade
from pecan import Pecan, request, response, override_template
from pecan import Pecan, request, response, override_template, redirect
from decorators import expose
__all__ = [

View File

@@ -1,10 +1,18 @@
from inspect import getargspec
def expose(template=None, content_type='text/html'):
if template == 'json': content_type = 'application/json'
def decorate(f):
# flag the method as exposed
f.exposed = True
# set a "pecan" attribute, where we will store details
if not hasattr(f, 'pecan'): f.pecan = {}
f.pecan['content_type'] = content_type
f.pecan.setdefault('template', []).append(template)
f.pecan.setdefault('content_types', {})[content_type] = template
# store the arguments for this controller method
f.pecan['argspec'] = getargspec(f)
return f
return decorate

View File

@@ -28,6 +28,10 @@ def override_template(template):
request.override_template = template
def redirect(location):
raise exc.HTTPFound(location=location)
class Pecan(object):
def __init__(self, root,
renderers = renderers,
@@ -70,6 +74,13 @@ class Pecan(object):
for hook in state.hooks:
getattr(hook, hook_type)(*args)
def get_validated_params(self, all_params, argspec):
valid_params = dict()
for param_name, param_value in all_params.iteritems():
if param_name in argspec.args:
valid_params[param_name] = param_value
return valid_params
def handle_request(self):
# lookup the controller, respecting content-type as requested
# by the file extension on the URI
@@ -94,8 +105,12 @@ class Pecan(object):
self.handle_hooks('before', state)
# get the result from the controller, properly handling wrap hooks
result = controller(**dict(state.request.str_params))
params = self.get_validated_params(
dict(state.request.str_params),
controller.pecan['argspec']
)
result = controller(**params)
# pull the template out based upon content type and handle overrides
template = controller.pecan.get('content_types', {}).get(content_type)
template = getattr(request, 'override_template', template)

View File

@@ -35,10 +35,6 @@ class JsonRenderer(object):
def render(self, template_path, namespace):
from jsonify import encode
result = encode(namespace)
print '*' * 80
print result
print type(result)
print '*' * 80
return result

View File

@@ -17,10 +17,34 @@ class PyTest(Command):
py.cmdline.pytest(py.std.sys.argv[2:])
#
# determine requirements
#
requirements = [
"WebOb >= 0.9.8",
"simplegeneric >= 0.7",
"Genshi >= 0.6",
"Kajiki >= 0.2.2",
"Mako >= 0.3",
"py >= 1.3.4",
"WebTest >= 1.2.2",
"Paste >= 1.7.5.1",
"PasteScript >= 1.7.3"
]
try:
import json
except:
requirements.append("simplejson >= 2.1.1")
#
# call setup
#
setup(
name = 'pecan',
version = version,
description = "A WSGI object-dispatching web framework, in the spirit of TurboGears, only much much smaller, with many fewer dependancies.",
description = "A WSGI object-dispatching web framework, in the spirit of TurboGears, only much much smaller, with many fewer dependencies.",
long_description = None,
classifiers = [],
keywords = '',
@@ -32,19 +56,8 @@ setup(
include_package_data = True,
zip_safe = True,
cmdclass = {'test': PyTest},
install_requires=[
"WebOb >= 0.9.8",
"simplegeneric >= 0.7",
"Genshi >= 0.6",
"Kajiki >= 0.2.2",
"Mako >= 0.3",
"py >= 1.3.4",
"WebTest >= 1.2.2",
"Paste >= 1.7.5.1",
"simplejson >= 2.1.1",
"PasteScript >= 1.7.3"
],
entry_points = """
install_requires = requirements,
entry_points = """
[paste.paster_create_template]
pecan-base = templates:NewProjectTemplate
""",

View File

@@ -1,4 +1,4 @@
from pecan import Pecan, expose, request, response
from pecan import Pecan, expose, request, response, redirect
from webtest import TestApp
class TestBase(object):
@@ -160,4 +160,36 @@ class TestEngines(object):
r = app.get('/')
assert r.status_int == 200
result = dict(loads(r.body))
assert result == expected_result
assert result == expected_result
def test_controller_parameters(self):
class RootController(object):
@expose('json')
def index(self, argument=None):
assert argument == 'value'
# arguments should get passed appropriately
app = TestApp(Pecan(RootController()))
r = app.get('/?argument=value')
assert r.status_int == 200
# extra arguments get stripped off
r = app.get('/?argument=value&extra=not')
assert r.status_int == 200
def test_redirect(self):
class RootController(object):
@expose()
def index(self):
redirect('/testing')
@expose()
def testing(self):
return 'it worked!'
app = TestApp(Pecan(RootController()))
r = app.get('/')
assert r.status_int == 302
r = r.follow()
assert r.status_int == 200
assert r.body == 'it worked!'