Modified:
/tipfy/app.py
/tipfy/config.py
/tipfy/handler.py
/tipfy/local.py
/tipfy/routing.py
=======================================
--- /tipfy/app.py Wed Mar 30 05:57:11 2011
+++ /tipfy/app.py Wed Mar 30 06:54:43 2011
@@ -42,9 +42,11 @@
"""
#: The WSGI app.
app = None
+ #: Exception caught by the WSGI app.
+ exception = None
#: URL adapter.
- url_adapter = None
- #: Matched :class:`tipfy.Rule`.
+ rule_adapter = None
+ #: Matched :class:`tipfy.routing.Rule`.
rule = None
#: Keyword arguments from the matched rule.
rule_args = None
@@ -62,13 +64,24 @@
if self.mimetype == 'application/json':
return json_decode(self.data)
+ def _get_rule_adapter(self):
+ # TODO: deprecation warning.
+ return self.rule_adapter
+
+ def _set_rule_adapter(self, adapter):
+ # TODO: deprecation warning.
+ self.rule_adapter = adapter
+
+ # Old name
+ url_adapter = property(_get_rule_adapter, _set_rule_adapter)
+
class Response(werkzeug.wrappers.Response):
"""A response object with default mimetype set to ``text/html``."""
default_mimetype = 'text/html'
-class Tipfy(object):
+class App(object):
"""The WSGI application."""
# Allowed request methods.
allowed_methods =
frozenset(['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST',
@@ -103,14 +116,14 @@
logging.getLogger().setLevel(logging.DEBUG)
def __call__(self, environ, start_response):
- """Shortcut for :meth:`Tipfy.wsgi_app`."""
- local.current_app = self
+ """Shortcut for :meth:`App.wsgi_app`."""
+ local.app = self
if self.debug and self.config['tipfy']['enable_debugger']:
return self._debugged_wsgi_app(environ, start_response)
return self.wsgi_app(environ, start_response)
- def wsgi_app(self, environ, start_response):
+ def dispatch(self, environ, start_response):
"""This is the actual WSGI application. This is not implemented in
:meth:`__call__` so that middlewares can be applied without losing
a
reference to the class. So instead of doing this::
@@ -134,7 +147,7 @@
"""
cleanup = True
try:
- request = self.request_class(environ)
+ local.request = request = self.request_class(environ)
request.app = self
if request.method not in self.allowed_methods:
abort(501)
@@ -165,12 +178,12 @@
def handle_exception(self, request, exception):
"""Handles an exception. To set app-wide error handlers, define
them
using the corresponent HTTP status code in the ``error_handlers``
- dictionary of :class:`Tipfy`. For example, to set a custom
+ dictionary of :class:`App`. For example, to set a custom
`Not Found` page::
class Handle404(RequestHandler):
- def handle_exception(self, exception):
- logging.exception(exception)
+ def __call__(self):
+ logging.exception(self.request.exception)
return Response('Oops! I could swear this page was
here!',
status=404)
@@ -207,6 +220,7 @@
if not handler:
raise
+ request.exception = exception
rv = handler(request.app, request)
if not isinstance(rv, werkzeug.wrappers.BaseResponse):
if hasattr(rv, '__call__'):
@@ -342,6 +356,9 @@
cls = self.config['tipfy']['session_store_class']
return werkzeug.utils.import_string(cls)
+ # Old names
+ wsgi_app = dispatch
+
def redirect(location, code=302, response_class=Response, body=None):
"""Returns a response object that redirects to the given location.
@@ -363,9 +380,10 @@
A :class:`Response` object with headers set for redirection.
"""
assert code in (301, 302, 303, 305, 307), 'invalid code'
- # not yet.
- #if location.startswith(('.', '/')):
- # location = urlparse.urljoin(get_request().url, location)
+
+ if location.startswith(('.', '/')):
+ # Make it absolute.
+ location = urlparse.urljoin(local.request.url, location)
display_location = location
if isinstance(location, unicode):
@@ -381,3 +399,7 @@
response = response_class(body, code, mimetype='text/html')
response.headers['Location'] = location
return response
+
+
+# Old names.
+Tipfy = App
=======================================
--- /tipfy/config.py Wed Mar 30 05:57:11 2011
+++ /tipfy/config.py Wed Mar 30 06:54:43 2011
@@ -27,7 +27,8 @@
of the first level one.
The configuration object is available as a ``config`` attribute of
- :class:`Tipfy`. If is instantiated and populated when the app is
built::
+ :class:`tipfy.app.App`. If is instantiated and populated when the app
+ is built::
config = {}
=======================================
--- /tipfy/handler.py Wed Mar 30 05:57:11 2011
+++ /tipfy/handler.py Wed Mar 30 06:54:43 2011
@@ -39,7 +39,7 @@
"""Initializes the handler.
:param app:
- A :class:`Tipfy` instance.
+ A :class:`tipfy.app.App` instance.
:param request:
A :class:`Request` instance.
"""
@@ -49,9 +49,10 @@
self.context = {}
def __call__(self):
- """Executes a handler method. This is called by :class:`Tipfy` and
- must return a :attr:`response_class` object. If :attr:`middleware`
are
- defined, use their hooks to process the request or handle
exceptions.
+ """Executes a handler method. This is called
by :class:`tipfy.app.App`
+ and must return a :attr:`response_class` object.
If :attr:`middleware`
+ are defined, use their hooks to process the request or handle
+ exceptions.
:returns:
A :attr:`response_class` instance.
@@ -157,9 +158,10 @@
def make_response(self, *rv):
"""Converts the returned value from a :class:`RequestHandler` to a
- response object that is an instance
of :attr:`Tipfy.response_class`.
-
- .. seealso:: :meth:`Tipfy.make_response`.
+ response object that is an instance of
+ :attr:`tipfy.app.App.response_class`.
+
+ .. seealso:: :meth:`tipfy.app.App.make_response`.
"""
return self.app.make_response(self.request, *rv)
@@ -193,10 +195,6 @@
"""
response_class = response_class or self.app.response_class
- if location.startswith(('.', '/')):
- # Make it absolute.
- location = urlparse.urljoin(self.request.url, location)
-
if empty:
body = ''
=======================================
--- /tipfy/local.py Wed Mar 30 05:57:11 2011
+++ /tipfy/local.py Wed Mar 30 06:54:43 2011
@@ -12,6 +12,31 @@
#: Context-local.
local = werkzeug.local.Local()
+
+#: A proxy to the current :class:`tipfy.app.App` instance.
+app = local('app')
+
+#: A proxy to the current :class:`tipfy.app.Request` instance.
+request = local('request')
+
+
+def get_app():
+ """Returns the current WSGI app instance.
+
+ :returns:
+ The current :class:`tipfy.app.App` instance.
+ """
+ return local.app
+
+def get_request():
+ """Returns the current request instance.
+
+ :returns:
+ The current :class:`tipfy.app.Request` instance.
+ """
+ return local.request
+
+
#: A proxy to the active handler for a request. This is intended to be
used by
#: functions called out of a handler context. Usage is generally
discouraged:
#: it is preferable to pass the handler as argument when possible and only
use
@@ -23,4 +48,4 @@
#: there to dynamically get the currently active handler.
current_handler = local('current_handler')
#: Same as current_handler, only for the active WSGI app.
-current_app = local('current_app')
+current_app = app
=======================================
--- /tipfy/routing.py Wed Mar 30 05:57:11 2011
+++ /tipfy/routing.py Wed Mar 30 06:54:43 2011
@@ -60,11 +60,11 @@
arguments.
"""
# Bind the URL map to the current request
- request.url_adapter = self.map.bind_to_environ(request.environ,
+ request.rule_adapter = self.map.bind_to_environ(request.environ,
server_name=self.get_server_name(request))
# Match the path against registered rules.
- match = request.url_adapter.match(return_rule=True)
+ match = request.rule_adapter.match(return_rule=True)
request.rule, request.rule_args = match
return match
@@ -130,7 +130,7 @@
anchor = kwargs.pop('_anchor', None)
full = kwargs.pop('_full', False) and not scheme and not netloc
- url = request.url_adapter.build(name, values=kwargs, method=method,
+ url = request.rule_adapter.build(name, values=kwargs,
method=method,
force_external=full)
if scheme or netloc:
@@ -401,6 +401,15 @@
self.regex = items[0]
+def url_for(_name, **kwargs):
+ """A proxy to :meth:`Router.url_for`.
+
+ .. seealso:: :meth:`Router.url_for`.
+ """
+ request = local.request
+ return request.rule_adapter.url_for(request, _name, kwargs)
+
+
# Add regex converter to the list of converters.
Map.default_converters = dict(Map.default_converters)
Map.default_converters['regex'] = RegexConverter