Merge default into py3k

--HG--
branch : py3k
master
Dustin C. Hatch 2012-11-27 19:12:59 -06:00
commit aba45a2107
8 changed files with 152 additions and 31 deletions

View File

@ -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 ---------------------------------------------------

View File

@ -14,6 +14,10 @@ Contents:
:maxdepth: 2
rationale
.. toctree::
:maxdepth: 1
reference/index
*Milla* is released under the terms of the `Apache License, version 2.0`_.

7
doc/reference/milla.rst Normal file
View File

@ -0,0 +1,7 @@
=====
milla
=====
.. automodule:: milla
:members:
:inherited-members:

View File

@ -20,6 +20,13 @@ from milla.auth.decorators import *
from webob.exc import *
from webob.request import *
from webob.response import *
import urllib
try:
import urllib.parse
except ImportError:
import urlparse
urllib.parse = urlparse
def allow(*methods):
'''Specify the allowed HTTP verbs for a controller callable
@ -35,3 +42,75 @@ def allow(*methods):
func.allowed_methods = methods
return func
return wrapper
class Response(Response):
''':py:class:`WebOb Response <webob.response.Response>` with minor tweaks
'''
class Request(Request):
''':py:class:`WebOb Request <webob.request.BaseRequest>` 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 = urllib.parse.urlsplit(url).path
if vars:
url += '?' + urllib.urlencode(vars)
return url
def static_resource(self, path):
'''Return a URL to the given static resource
This method combines the defined static resource root URL with the
given path to construct a complete URL to the given resource. The
resource root should be defined in the application configuration
dictionary, under the name ``milla.static_root``, for example::
app = milla.Application(dispatcher)
app.config.update({
'milla.static_root': '/static/'
})
Then, calling ``static_resource`` on a :py:class:`Request` object
(i.e. inside a controller callable) would combine the given path
with ``/static/``, like this::
request.static_resource('/images/foo.png')
would return ``/static/images/foo.png``.
If no ``milla.static_root`` key is found in the configuration
dictionary, the path will be returned unaltered.
:param path: Path to the resource, relative to the defined root
'''
try:
root = self.config['milla.static_root']
except KeyError:
return path
if path.startswith('/'):
path = path[1:]
if not root.endswith('/'):
root += '/'
return urllib.parse.urljoin(root, path)

View File

@ -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

View File

@ -23,7 +23,8 @@ from one or more of these classes can make things significantly easier.
:Updater: $Author$
'''
import milla
import datetime
import milla.util
import pkg_resources
@ -53,6 +54,9 @@ class FaviconController(Controller):
used as the favicon, defaults to 'image/x-icon' (Windows ICO format)
'''
#: Number of days in the future to set the cache expiration for the icon
EXPIRY_DAYS = 365
def __init__(self, icon=None, content_type='image/x-icon'):
if icon:
try:
@ -72,4 +76,7 @@ class FaviconController(Controller):
response = milla.Response()
response.app_iter = self.icon
response.headers['Content-Type'] = self.content_type
expires = (datetime.datetime.utcnow() +
datetime.timedelta(days=self.EXPIRY_DAYS))
response.headers['Expires'] = milla.util.http_date(expires)
return response

View File

@ -24,12 +24,7 @@ import functools
import milla
import re
import sys
import urllib
try:
import urllib.parse
except ImportError:
import urlparse
urllib.parse = urlparse
import warnings
class Router(object):
'''A dispatcher that maps arbitrary paths to controller callables
@ -224,11 +219,20 @@ class Generator(object):
A common pattern is to wrap this in a stub function::
url = Generator(request).generate
.. deprecated:: 0.2
Use :py:meth:`milla.Request.relative_url` instead.
'''
def __init__(self, request, path_only=True):
self.request = request
self.path_only = path_only
warnings.warn(
'Use of Generator is deprecated; '
'use milla.Request.relative_url instead',
DeprecationWarning,
stacklevel=2
)
def generate(self, *segments, **vars):
'''Combines segments and the application's URL into a new URL
@ -238,10 +242,7 @@ class Generator(object):
while path.startswith('/'):
path = path[1:]
url = self.request.relative_url(path, to_application=True)
if self.path_only:
split = urllib.parse.urlsplit(url)
url = split.path
if vars:
url += '?' + urllib.urlencode(vars)
return url
return self.request.relative_url(path,
to_application=True,
path_only=self.path_only,
**vars)

View File

@ -21,6 +21,10 @@ Please give me a docstring!
:Updater: $Author$
'''
from wsgiref.handlers import format_date_time
import datetime
import time
def asbool(val):
'''Test a value for truth
@ -47,3 +51,18 @@ def asbool(val):
if val in ('false', 'no', 'f', 'n', 'off', '0'):
return False
return True
def http_date(date):
'''Format a datetime object as a string in RFC 1123 format
This function returns a string representing the date according to
RFC 1123. The string returned will always be in English, as
required by the specification.
:param date: A :py:class:`datetime.datetime` object
:return: RFC 1123-formatted string
'''
stamp = time.mktime(date.timetuple())
return format_date_time(stamp)