kopia lustrzana https://gitlab.com/marnanel/chapeau
91 wiersze
2.5 KiB
Python
91 wiersze
2.5 KiB
Python
# view_for_mimetype.py
|
|
#
|
|
# Part of kepi.
|
|
# Copyright (c) 2018-2020 Marnanel Thurman.
|
|
# Licensed under the GNU Public License v2.
|
|
#
|
|
# This might work better as a standalone module,
|
|
# separate from kepi?
|
|
|
|
import logging
|
|
logger = logging.getLogger(name='kepi')
|
|
|
|
from kepi.tophat_ui.parse_accept import parse_accept_header
|
|
from django.http import HttpResponse
|
|
|
|
def view_for_mimetype(
|
|
views,
|
|
default = None,
|
|
):
|
|
"""
|
|
Returns a Django view function which can route requests
|
|
to other view functions based on the incoming Accept header.
|
|
|
|
Params:
|
|
views - a list of (type, subtype, view) triplets
|
|
e.g. ('text', 'html', HelloWorldView)
|
|
|
|
default - the default to return if the Accept header
|
|
can't otherwise be satisfied.
|
|
|
|
If you don't give a default, the view function returns
|
|
a new HttpResponse with status_code==406, i.e. "Not Acceptable".
|
|
See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406
|
|
|
|
As a special case, if request is None, returns the list of views.
|
|
A default value will be at the end, with type and subtype set to None.
|
|
"""
|
|
|
|
def _view_for_mimetype_inner(
|
|
request,
|
|
*args, **kwargs,
|
|
):
|
|
|
|
if request is None:
|
|
result = views.copy()
|
|
|
|
if default is not None:
|
|
result.append((None, None, default))
|
|
|
|
return result
|
|
|
|
accept_header = request.headers.get('Accept', '')
|
|
accept_parsed = parse_accept_header(accept_header)
|
|
|
|
logger.debug("Accept=%s -> %s", accept_header, accept_parsed)
|
|
logger.debug("Views: %s", views)
|
|
|
|
for want_type, want_subtype, params, q in accept_parsed:
|
|
|
|
for have_type, have_subtype, view in views:
|
|
|
|
if want_type != have_type:
|
|
continue
|
|
|
|
if want_subtype not in (have_subtype, '*'):
|
|
continue
|
|
|
|
logger.debug(' -- found %s/%s: %s',
|
|
have_type, have_subtype, view)
|
|
|
|
result = view(request,
|
|
*args, **kwargs,
|
|
)
|
|
return result
|
|
|
|
if default is not None:
|
|
logger.debug(' -- using default: %s',
|
|
view)
|
|
|
|
result = default(request,
|
|
*args, **kwargs,
|
|
)
|
|
return result
|
|
else:
|
|
logger.debug(' -- none found; 406')
|
|
|
|
# return 406 Not Acceptable
|
|
return HttpResponse(status=406)
|
|
|
|
return _view_for_mimetype_inner
|