MyCoServer/mycoserver/wsgi_helpers.py
2014-01-12 01:33:07 +01:00

171 lines
5.5 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
import collections
import json
from markupsafe import Markup
from webhelpers.html import tags
import webob.dec
import webob.exc
from . import templates
N_ = lambda message: message
errors_explanation = {
400: N_("Request is faulty"),
401: N_("Access is restricted to authorized persons."),
403: N_("Access is forbidden."),
404: N_("The requested page was not found."),
}
errors_message = {
401: N_("You must login to access this page."),
}
errors_title = {
400: N_("Unable to Access"),
401: N_("Access Denied"),
403: N_("Access Denied"),
404: N_("Unable to Access"),
}
def bad_request(ctx, **kw):
return error(ctx, 400, **kw)
def discard_empty_items(data):
if isinstance(data, collections.Mapping):
# Use type(data) to keep OrderedDicts.
data = type(data)(
(name, discard_empty_items(value))
for name, value in data.iteritems()
if value is not None
)
return data
def error(ctx, code, **kw):
response = webob.exc.status_map[code](headers=kw.pop('headers', None))
if code != 204: # No content
body = kw.pop('body', None)
if body is None:
template_path = kw.pop('template_path', '/http-error.mako')
explanation = kw.pop('explanation', None)
if explanation is None:
explanation = errors_explanation.get(code)
explanation = ctx._(explanation) if explanation is not None else response.explanation
message = kw.pop('message', None)
if message is None:
message = errors_message.get(code)
if message is not None:
message = ctx._(message)
comment = kw.pop('comment', None)
if isinstance(comment, dict):
comment = tags.ul(u'{0} : {1}'.format(key, value) for key, value in comment.iteritems())
elif isinstance(comment, list):
comment = tags.ul(comment)
title = kw.pop('title', None)
if title is None:
title = errors_title.get(code)
title = ctx._(title) if title is not None else response.status
body = templates.render(ctx, template_path,
comment=comment,
explanation=explanation,
message=message,
response=response,
title=title,
**kw)
response.body = body.encode('utf-8') if isinstance(body, unicode) else body
return response
def forbidden(ctx, **kw):
return error(ctx, 403, **kw)
def method_not_allowed(ctx, **kw):
return error(ctx, 405, **kw)
def no_content(ctx, headers=None):
return error(ctx, 204, headers=headers)
def not_found(ctx, **kw):
return error(ctx, 404, **kw)
def redirect(ctx, code=302, location=None, **kw):
assert location is not None
location_str = location.encode('utf-8') if isinstance(location, unicode) else location
response = webob.exc.status_map[code](headers=kw.pop('headers', None), location=location_str)
body = kw.pop('body', None)
if body is None:
template_path = kw.pop('template_path', '/http-error.mako')
explanation = kw.pop('explanation', None)
if explanation is None:
explanation = Markup(u'{0} <a href="{1}">{1}</a>.').format(ctx._(u"You'll be redirected to page"), location)
message = kw.pop('message', None)
if message is None:
message = errors_message.get(code)
if message is not None:
message = ctx._(message)
title = kw.pop('title', None)
if title is None:
title = ctx._("Redirection in progress...")
body = templates.render(ctx, template_path,
comment=kw.pop('comment', None),
explanation=explanation,
message=message,
response=response,
title=title,
**kw)
response.body = body.encode('utf-8') if isinstance(body, unicode) else body
return response
def respond_json(ctx, data, code=None, headers=None, jsonp=None):
"""Return a JSON response.
This function is optimized for JSON following
`Google JSON Style Guide <http://google-styleguide.googlecode.com/svn/trunk/jsoncstyleguide.xml>`_, but will handle
any JSON except for HTTP errors.
"""
if isinstance(data, collections.Mapping):
# Remove null properties as recommended by Google JSON Style Guide.
data = discard_empty_items(data)
error = data.get('error')
else:
error = None
if headers is None:
headers = []
if jsonp:
headers.append(('Content-Type', 'application/javascript; charset=utf-8'))
else:
headers.append(('Content-Type', 'application/json; charset=utf-8'))
if error:
code = code or error['code']
assert isinstance(code, int)
response = webob.exc.status_map[code](headers=headers)
if error.get('code') is None:
error['code'] = code
if error.get('message') is None:
error['message'] = response.title
else:
response = ctx.req.response
if code is not None:
response.status = code
response.headers.update(headers)
text = unicode(json.dumps(data, encoding='utf-8', ensure_ascii=False, indent=2, sort_keys=True))
if jsonp:
text = u'{0}({1})'.format(jsonp, text)
response.text = text
return response
def unauthorized(ctx, **kw):
return error(ctx, 401, **kw)