diff options
| author | Bert JW Regeer <bertjw@regeer.org> | 2016-04-12 18:52:25 -0600 |
|---|---|---|
| committer | Bert JW Regeer <bertjw@regeer.org> | 2016-04-12 20:21:43 -0600 |
| commit | cb67e01c07be14994229f584d8b6b6edcf84da78 (patch) | |
| tree | 8d64f31bebdda8a2773bb02a1d02eb64d09fcc71 | |
| parent | efaf7300c9c3ef2a795aae7f724bf5b02e96cd75 (diff) | |
| download | pyramid-cb67e01c07be14994229f584d8b6b6edcf84da78.tar.gz pyramid-cb67e01c07be14994229f584d8b6b6edcf84da78.tar.bz2 pyramid-cb67e01c07be14994229f584d8b6b6edcf84da78.zip | |
Using WebOb's acceptparse find best mimetype to use
We default to text/plain.
| -rw-r--r-- | pyramid/httpexceptions.py | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/pyramid/httpexceptions.py b/pyramid/httpexceptions.py index 8bf9a0a72..ef1e5c144 100644 --- a/pyramid/httpexceptions.py +++ b/pyramid/httpexceptions.py @@ -123,12 +123,14 @@ The subclasses of :class:`~_HTTPMove` field. Reflecting this, these subclasses have one additional keyword argument: ``location``, which indicates the location to which to redirect. """ +import json from string import Template from zope.interface import implementer from webob import html_escape as _html_escape +from webob.acceptparse import Accept from pyramid.compat import ( class_types, @@ -214,7 +216,7 @@ ${body}''') empty_body = False def __init__(self, detail=None, headers=None, comment=None, - body_template=None, **kw): + body_template=None, json_formatter=None, **kw): status = '%s %s' % (self.code, self.title) Response.__init__(self, status=status, **kw) Exception.__init__(self, detail) @@ -225,6 +227,8 @@ ${body}''') if body_template is not None: self.body_template = body_template self.body_template_obj = Template(body_template) + if json_formatter is not None: + self._json_formatter = json_formatter if self.empty_body: del self.content_type @@ -233,31 +237,64 @@ ${body}''') def __str__(self): return self.detail or self.explanation + def _json_formatter(self, status, body, title, environ): + return {'message': body, + 'code': status, + 'title': self.title} + def prepare(self, environ): if not self.body and not self.empty_body: html_comment = '' comment = self.comment or '' - accept = environ.get('HTTP_ACCEPT', '') - if accept and 'html' in accept or '*/*' in accept: + accept_value = environ.get('HTTP_ACCEPT', '') + accept = Accept(accept_value) + match = accept.best_match( + ['application/json', + 'text/html', + 'text/plain'], default_match='text/plain') + + if match == 'text/html': self.content_type = 'text/html' + self.charset = 'utf-8' escape = _html_escape page_template = self.html_template_obj br = '<br/>' if comment: html_comment = '<!-- %s -->' % escape(comment) + elif match == 'application/json': + self.content_type = 'application/json' + self.charset = '' + escape = _no_escape + br = '\n' + if comment: + html_comment = escape(comment) + + class JsonPageTemplate(object): + def __init__(self, excobj): + self.excobj = excobj + + def substitute(self, status, body): + jsonbody = self.excobj._json_formatter( + status=status, + body=body, title=self.excobj.title, + environ=environ) + return json.dumps(jsonbody) + + page_template = JsonPageTemplate(self) else: self.content_type = 'text/plain' + self.charset = 'utf-8' escape = _no_escape page_template = self.plain_template_obj br = '\n' if comment: html_comment = escape(comment) args = { - 'br':br, + 'br': br, 'explanation': escape(self.explanation), 'detail': escape(self.detail or ''), 'comment': escape(comment), - 'html_comment':html_comment, + 'html_comment': html_comment, } body_tmpl = self.body_template_obj if HTTPException.body_template_obj is not body_tmpl: @@ -1001,8 +1038,8 @@ class HTTPInternalServerError(HTTPServerError): code = 500 title = 'Internal Server Error' explanation = ( - 'The server has either erred or is incapable of performing ' - 'the requested operation.') + 'The server has either erred or is incapable of performing ' + 'the requested operation.') class HTTPNotImplemented(HTTPServerError): """ |
