From 2980b438da5c59f079546fa462cf3a9f98bcc5a0 Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Sat, 3 Nov 2012 19:03:13 -0500 Subject: [PATCH] Subclass WebOb Request and override relative_url (see #3) --- doc/conf.py | 6 +++++- doc/reference/milla.rst | 7 +++++++ src/milla/__init__.py | 35 +++++++++++++++++++++++++++++++++++ src/milla/app.py | 30 +++++++++++++++--------------- 4 files changed, 62 insertions(+), 16 deletions(-) create mode 100644 doc/reference/milla.rst diff --git a/doc/conf.py b/doc/conf.py index 8a3a155..1a8bea0 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -25,7 +25,8 @@ import sys, os # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.viewcode'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', + 'sphinx.ext.viewcode', 'sphinx.ext.intersphinx'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -86,6 +87,9 @@ pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] +intersphinx_mapping = { + 'webob': ('http://docs.webob.org/en/latest/', None) +} # -- Options for HTML output --------------------------------------------------- diff --git a/doc/reference/milla.rst b/doc/reference/milla.rst new file mode 100644 index 0000000..5800ca2 --- /dev/null +++ b/doc/reference/milla.rst @@ -0,0 +1,7 @@ +===== +milla +===== + +.. automodule:: milla + :members: + :inherited-members: diff --git a/src/milla/__init__.py b/src/milla/__init__.py index c391afb..3aa3d04 100644 --- a/src/milla/__init__.py +++ b/src/milla/__init__.py @@ -20,6 +20,8 @@ from webob.exc import * from webob.request import * from webob.response import * from auth.decorators import * +import urllib +import urlparse def allow(*methods): '''Specify the allowed HTTP verbs for a controller callable @@ -35,3 +37,36 @@ def allow(*methods): func.allowed_methods = methods return func return wrapper + + +class Response(Response): + ''':py:class:`WebOb Response ` with minor tweaks + ''' + + +class Request(Request): + ''':py:class:`WebOb Request ` with minor tweaks + ''' + + ResponseClass = Response + + def relative_url(self, other_url, to_application=True, path_only=True, + **vars): + '''Create a new URL relative to the request URL + + :param other_url: relative path to join with the request URL + :param to_application: If true, generated URL will be relative + to the application's root path, otherwise relative to the + server root + :param path_only: If true, scheme and host will be omitted + + Any other keyword arguments will be encoded and appended to the URL + as querystring arguments. + ''' + + url = super(Request, self).relative_url(other_url, to_application) + if path_only: + url = urlparse.urlsplit(url).path + if vars: + url += '?' + urllib.urlencode(vars) + return url diff --git a/src/milla/app.py b/src/milla/app.py index e57eed6..d7117e1 100644 --- a/src/milla/app.py +++ b/src/milla/app.py @@ -1,11 +1,11 @@ # Copyright 2011 Dustin C. Hatch -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -31,19 +31,19 @@ __all__ = ['Application'] class Application(object): '''Represents a Milla web application - + Constructing an ``Application`` instance needs a dispatcher, or alternatively, a root object that will be passed to a new - :py:class:`milla.dispatch.traversal.Traverser`. - + :py:class:`milla.dispatch.traversal.Traverser`. + :param root: A root object, passed to a traverser, which is automatically created if a root is given - :param dispatcher: An object implementing the dispatcher protocol - + :param dispatcher: An object implementing the dispatcher protocol + ``Application`` instances are WSGI applications. - + .. py:attribute:: config - + A mapping of configuration settings. For each request, the configuration is copied and assigned to ``request.config``. ''' @@ -65,7 +65,7 @@ class Application(object): else: return HTTPNotFound()(environ, start_response) - request = webob.Request(environ) + request = milla.Request(environ) request.config = self.config.copy() # Sometimes, hacky applications will try to "emulate" some HTTP @@ -88,7 +88,7 @@ class Application(object): start_response) start_response_wrapper = StartResponseWrapper(start_response) - request.start_response = start_response_wrapper + request.start_response = start_response_wrapper try: # If the callable has an __before__ attribute, call it if hasattr(func, '__before__'): @@ -136,11 +136,11 @@ class Application(object): return response.app_iter class StartResponseWrapper(): - + def __init__(self, start_response): self.start_response = start_response self.called = False - + def __call__(self, *args, **kwargs): self.called = True - return self.start_response(*args, **kwargs) \ No newline at end of file + return self.start_response(*args, **kwargs)